【问题标题】:When I shuffle a copy of a DataFrame, why the original DataFrame is also shuffled? [duplicate]当我洗牌一个 DataFrame 的副本时,为什么原来的 DataFrame 也被洗牌了? [复制]
【发布时间】:2016-04-07 18:34:54
【问题描述】:

这是输入,

    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

然后我创建它的副本。我假设我实际上克隆了该对象,而不仅仅是创建一个新的链接。我想打乱原始 DataFrame 的副本,同时保持原始 DataFrame 不变。

    df2=df1.copy(deep= True)

在我洗牌 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')

有人说这是因为 Deep Copy 实际上并不深。然后我尝试查看每个DataFrame的索引是否引用了不同的对象。 我试过了,

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

我有,

    156017776
    156170112
    False

现在我更加困惑了。如果它们是不同的对象,为什么我的解决方案失败以及如何实现我想要的? 这不是this post 的重复,因为当时深拷贝并没有创建新的索引对象,但现在副本确实有一个新的索引对象。但是,问题仍然存在。 (我使用的是熊猫 0.17.0;numpy 1.10.1)

【问题讨论】:

    标签: python numpy pandas random


    【解决方案1】:

    是的,您的发现与我测试的结果一致。

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

    好像在pandas中,日期框复制会排除索引(df.index不会被深度复制)

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

    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
    

    结果如下:

    Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype='int64')
    Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype='int64')
    

    希望对你有帮助。

    【讨论】:

    • 你为什么认为你解决了这个问题?当您打印 df1.index 时,序列仍然发生变化,它是 [0, 6, 3, 4, 7, 5, 8, 9, 1, 2]。但是,我希望 df1 保持不变。
    • @PeterLi 是的,你是对的。我想我复制了错误的行。它将由 df2.index = copy.deepcopy(df1.index) 修复
    【解决方案2】:

    df1.indexdf2.index 的 ID 不同,但 df1.index.valuesdf2.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)
    

    np.random.shuffle 就地更改值,因此您可以使用np.random.permutation 并分配给df2.index 结果:

    In [73]: df2.index = np.random.permutation(df2.index)
    
    In [74]: df1.index
    Out[74]: Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype='int64')
    
    In [75]: df2.index
    Out[75]: Int64Index([6, 2, 1, 8, 7, 0, 4, 5, 3, 9], dtype='int64')
    

    但仍然很奇怪为什么df1.indexdf2.index 有不同的 ID 而它们的值却没有。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多