熊猫:如何使用apply来创建新的数据帧

时间:2015-05-11 09:33:19

标签: python pandas dataframe apply

我在Python Pandas中发现了一个奇怪的行为,并想问这是不是我的错,或者它是否是一个实际的程序错误。 我们采用以下DataFrame:

data = DataFrame({'k2':[1, 2, 3, ], 'name':['joe', 'mark', 'carl']})
data.set_index('name', drop=False, inplace=True)

如果我创建一个返回类似

的Series对象的函数
def my_test(i, x):
     x['interrel'] = x.apply(lambda row: i['k2'] - row['k2'] if i['name'] != row['name'] else 0, axis=1)
     print x['interrel'] 
     return x['interrel']

并使用

使用应用于创建的DataFrame的函数
  data.apply(lambda row: my_test(row, data), axis=1)

我输入的所有内容都是最后计算的行时间三。但是,my_test函数中的print语句显示计算是正确的。似乎只有特定的系列对象没有正确附加。

你能重建这个问题吗?关于apply函数的使用我有什么不妥吗?

请注意这只是一个例子,我不是要求另一种方式来做Pandas中的成对差异

感谢任何帮助

1 个答案:

答案 0 :(得分:1)

因为您已经将data df作为参考传递,并且每次都通过调用func中的apply直接指定它,然后用最后一个操作覆盖它:

In [20]:

def my_test(i, x):
    x['interrel'] = x.apply(lambda row: i['k2'] - row['k2'] if i['name'] != row['name'] else 0, axis=1)
    #print(x['interrel'])
    print("x-----",x, "\n-------")
    return x['interrel']
data.apply(lambda row: my_test(row, data), axis=1)
x-----       k2  name  interrel
name                    
joe    1   joe         0
mark   2  mark        -1
carl   3  carl        -2 
-------
x-----       k2  name  interrel
name                    
joe    1   joe         0
mark   2  mark        -1
carl   3  carl        -2 
-------
x-----       k2  name  interrel
name                    
joe    1   joe         1
mark   2  mark         0
carl   3  carl        -1 
-------
x-----       k2  name  interrel
name                    
joe    1   joe         2
mark   2  mark         1
carl   3  carl         0 
-------
Out[20]:
name  joe  mark  carl
name                 
joe     2     1     0
mark    2     1     0
carl    2     1     0

如果您发现传递数据副本然后在原始数据副本上执行操作并返回正确的结果,您可以看到data df未受影响:

 In [22]:

def my_test(i, x):
    x['interrel'] = x.apply(lambda row: i['k2'] - row['k2'] if i['name'] != row['name'] else 0, axis=1)
    #print(x['interrel'])
    print("x-----",x, "\n-------")
    return x['interrel']
print(data.apply(lambda row: my_test(row, data.copy()), axis=1))
print(data)
x-----       k2  name  interrel
name                    
joe    1   joe         0
mark   2  mark        -1
carl   3  carl        -2 
-------
x-----       k2  name  interrel
name                    
joe    1   joe         0
mark   2  mark        -1
carl   3  carl        -2 
-------
x-----       k2  name  interrel
name                    
joe    1   joe         1
mark   2  mark         0
carl   3  carl        -1 
-------
x-----       k2  name  interrel
name                    
joe    1   joe         2
mark   2  mark         1
carl   3  carl         0 
-------
name  joe  mark  carl
name                 
joe     0    -1    -2
mark    1     0    -1
carl    2     1     0
      k2  name  interrel
name                    
joe    1   joe         2
mark   2  mark         1
carl   3  carl         0