当我洗牌一个数据帧的副本时,为什么原始数据帧也被洗牌?

2024-04-24 23:36:02 发布

您现在位置:Python中文网/ 问答频道 /正文

这是输入

    df1= pd.DataFrame(np.random.randn(10,3), columns= list("ABC") )
              A         B         C
    0  0.468682 -0.136178  0.418900
    1 -0.362995 -0.111931  0.433537
    2 -1.194483 -0.844683 -1.022719
    3  0.531893 -1.032088 -1.683009
    4  2.113807 -0.450628  0.004971
    5  0.141548 -0.621090 -0.135580
    6  0.128670 -0.460494 -0.016550
    7 -0.099141 -0.010140 -0.066042
    8  1.317759 -1.522207 -0.234447
    9 -0.039051 -1.395751 -0.431717

然后我创建一个副本。我假设我实际上克隆了这个对象,而不仅仅是创建一个新的链接。我想洗牌原始数据帧的副本,同时保持原始数据帧不变。在

^{pr2}$

在我洗牌了df2之后

    np.random.shuffle(df2.index.values)

然后我发现df2和df1都被洗牌了。在

    df1.index
    Out[177]: Int64Index([7, 8, 0, 1, 3, 4, 6, 2, 5, 9], dtype='int64')

    df2.index
    Out[178]: Int64Index([7, 8, 0, 1, 3, 4, 6, 2, 5, 9], dtype='int64')

有人说这是因为深拷贝实际上并不深。然后我尝试查看每个数据帧的索引是否引用不同的对象。 我试过了

    print(id(df1.index))
    print(id(df2.index))
    df1.index is df2.index

我有

    156017776
    156170112
    False

现在我更困惑了。如果它们是不同的对象,为什么我的解决方案失败,以及如何实现我想要的? 这不是this post的副本,因为那时deep copy不会创建新的index对象,但现在副本有了新的索引反对。但是,问题仍然存在。 (我使用的是pandas 0.17.0;numpy 1.10.1)


Tags: 对象id原始数据indexnp副本randomout
2条回答

是的,你的发现和我测试的结果是一致的。在

我在网上找到这个https://github.com/pydata/pandas/issues/4202

似乎在熊猫中,日期帧复制将排除索引(测向索引不会被深度复制)

我尝试了如下可能的解决方法:

df1= pd.DataFrame(np.random.randn(10,3), columns= list("ABC") )
print df1.index
df2=df1.copy(deep= True)
df2.index = copy.deepcopy(df1.index)
np.random.shuffle(df2.index.values)
print df1.index

结果如下:

^{pr2}$

希望有帮助。在

df1.index和{}的ID不同,但是df1.index.values和{}具有相同的ID:

In [68]: id(df1.index), id(df2.index)
Out[68]: (140032214366920, 140032214391720)

In [69]: id(df1.index.values), id(df2.index.values)
Out[69]: (140032213182304, 140032213182304)

^{}就地更改值,以便可以使用^{}并将其分配给df2.index结果:

^{pr2}$

但是仍然奇怪的是,df1.index和{}具有不同的id,但是它们的值却没有。在

相关问题 更多 >