首页 > 解决方案 > 自定义函数中未分配的新列(Python)

问题描述

我的目标是定义一个函数来覆盖给它的任何输入。它应该向对象添加列,然后将其与函数本身中定义的数据框合并。我注意到我手动声明的列正在写入对象上,但没有添加合并产生的列。

这就是我的数据df,看起来像:

  col1                  col2
0    Q       V V V V V V V V
1    Q             V V V V V
2    Q       V V V V V V V V
3    Q   V V-- V V V V V V V
4    Q   V V V V V V V V V V

在这个虚拟示例中,我想编写一个自定义函数,将一列全为一的列添加到输入中,然后将其与另一个数据框合并。请注意,该函数不会返回另一个对象,而是会覆盖提供给它的对象。

def f(data):
    from pandas import DataFrame, merge  
    data['ones'] = 1
    temp = DataFrame({'col1':['C','Q','M'], 'col3':[14,15,30]})
    data = merge(data, temp, on='col1')
f(df)
  col1                  col2  ones
0    Q       V V V V V V V V     1
1    Q             V V V V V     1
2    Q       V V V V V V V V     1
3    Q   V V-- V V V V V V V     1
4    Q   V V V V V V V V V V     1

为什么 is 时merge没有被覆盖df的结果df['ones']

标签: pythonpandas

解决方案


Pandas 中的项目分配发生在适当的位置。很像字典,执行:

my_dict = {}
my_dict["ones"] = 1 # modifies the dictionary in place

然而,大多数 pandas 函数并没有就地运行,它们创建一个副本并返回该副本。对于带有inplace关键字参数的函数也是如此。将 设置inplace为 true 仅模拟实际的“就地”更改,首先创建对象的副本,然后用修改后的对象替换原始对象 - 不更新数据子集。

您可以通过执行与上述相同的操作并将您的函数更改为读取来实现您的结果:

def inplace_merge(df1, df2, on):
    # Modifies df1 inplace
    #  probably not as efficient as an actual 
    #  merge in terms of performance
    
    df2 = df2.set_index(on).reindex(df1[on])
    for col in df2:
        df1[col] = df2[col].values
    

def f(data):
    from pandas import DataFrame, merge  
    data['ones'] = 1
    
    temp = DataFrame({'col1':['C','Q','M'], 'col3':[14,15,30]})
    inplace_merge(data, temp, on="col1")


f(df)

print(df)
  col1                 col2  ones  col3
0    Q      V V V V V V V V     1    15
1    Q            V V V V V     1    15
2    Q      V V V V V V V V     1    15
3    Q  V V-- V V V V V V V     1    15
4    Q  V V V V V V V V V V     1    15

但是,我强烈建议您不要使用大量修改单个数据帧的函数。传递副本,pandas 旨在易于使用,而不是易于内存消耗。还有其他库,例如vaex可以处理具有零复制功能的类似 DataFrame 的对象。


推荐阅读