繁体   English   中英

包含 python 对象(如列表)的 Deepcopy Pandas DataFrame

[英]Deepcopy pandas DataFrame containing python objects (such as lists)

需要帮助理解变量赋值、指针、...

以下是可重现的。

import pandas as pd

df = pd.DataFrame({
    'listData': [
        ['c', 'f', 'd', 'a', 'e', 'b'], 
        [5, 2, 1, 4, 3]
    ]})

df['listDataSort'] = df['listData']

给出:

             listData        listDataSort
0  [c, f, d, a, e, b]  [c, f, d, a, e, b]
1     [5, 2, 1, 4, 3]     [5, 2, 1, 4, 3]

如果我只想对listDataSort列中的列表进行排序,我可以尝试:

df['listDataSort'].apply(lambda l: l.sort())
df

但是,这会就地对两列中的列表进行排序。

             listData        listDataSort
0  [a, b, c, d, e, f]  [a, b, c, d, e, f]
1     [1, 2, 3, 4, 5]     [1, 2, 3, 4, 5]

我可以通过执行以下操作来解决此问题:

df = pd.DataFrame({
    'listData': [
        ['c', 'f', 'd', 'a', 'e', 'b'], 
        [5, 2, 1, 4, 3]
    ]})

df['listDataSort'] = df['listData'].apply(sorted)

给予:

             listData        listDataSort
0  [c, f, d, a, e, b]  [a, b, c, d, e, f]
1     [5, 2, 1, 4, 3]     [1, 2, 3, 4, 5]

将 df 分配给不同的变量,例如 df2 仍然将所有内容更改回原始源列表。 此外,如何基于现有数据帧创建新数据帧,以便我可以对新数据帧进行更改,而无需对现有数据帧进行相同更改?

df = pd.DataFrame({
    'listData': [
        ['c', 'f', 'd', 'a', 'e', 'b'], 
        [5, 2, 1, 4, 3]
    ]})

df2 = df
print('\ndf\n', df)
print('\ndf2\n', df2)

df2['listDataSort'] = df2['listData']
print('\ndf\n', df)
print('\ndf2\n', df2)

df2['listDataSort'].apply(lambda l: l.sort())
print('\ndf\n', df)
print('\ndf2\n', df2)

印刷:

df
             listData
0  [c, f, d, a, e, b]
1     [5, 2, 1, 4, 3]

df2
             listData
0  [c, f, d, a, e, b]
1     [5, 2, 1, 4, 3]

df
             listData        listDataSort
0  [c, f, d, a, e, b]  [c, f, d, a, e, b]
1     [5, 2, 1, 4, 3]     [5, 2, 1, 4, 3]

df2
             listData        listDataSort
0  [c, f, d, a, e, b]  [c, f, d, a, e, b]
1     [5, 2, 1, 4, 3]     [5, 2, 1, 4, 3]

df
             listData        listDataSort
0  [a, b, c, d, e, f]  [a, b, c, d, e, f]
1     [1, 2, 3, 4, 5]     [1, 2, 3, 4, 5]

df2
             listData        listDataSort
0  [a, b, c, d, e, f]  [a, b, c, d, e, f]
1     [1, 2, 3, 4, 5]     [1, 2, 3, 4, 5]

还:

df = pd.DataFrame({
    'listData': [
        ['c', 'f', 'd', 'a', 'e', 'b'], 
        [5, 2, 1, 4, 3]
    ]})
print('\ndf\n', df)

df3 = df
df3['listDataSort'] = df3['listData'].apply(sorted)
print('\ndf\n', df)
print('\ndf3\n', df3)

印刷:

df
             listData
0  [c, f, d, a, e, b]
1     [5, 2, 1, 4, 3]

df
             listData        listDataSort
0  [c, f, d, a, e, b]  [a, b, c, d, e, f]
1     [5, 2, 1, 4, 3]     [1, 2, 3, 4, 5]

df3
             listData        listDataSort
0  [c, f, d, a, e, b]  [a, b, c, d, e, f]
1     [5, 2, 1, 4, 3]     [1, 2, 3, 4, 5]

当你跑

df['listDataSort'] = df['listData']

您所做的就是将列表的引用复制到新列。 这意味着只执行浅拷贝并且两列引用相同的列表。 因此,对一列的任何更改都可能会影响另一列。

您可以使用带有sorted的列表理解,它返回数据的副本。 这对您来说应该是最简单的选择。

df['listDataSort'] = [sorted(x) for x in df['listDataSort']]
df

             listData        listDataSort
0  [c, f, d, a, e, b]  [a, b, c, d, e, f]
1     [5, 2, 1, 4, 3]     [1, 2, 3, 4, 5]

现在,当涉及到制作整个 DataFrame 的副本的问题时,事情稍微复杂一些。 我会推荐deepcopy

import copy
df2 = df.apply(copy.deepcopy)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM