2015-01-12 42 views
0

这一个不平凡的功能大熊猫据帧一列是这一个后续问题:how to select/add a column to pandas dataframe based on a function of other columns?如何选择/添加基于其他列

有一个数据帧,我想选择相匹配的行一些标准。该标准是其他列的值和一些附加值的函数。

这里是一个玩具例子:

>> df = pd.DataFrame({'A': [1,2,3,4,5,6,7,8,9], 
       'B': [randint(1,9) for x in xrange(9)], 
       'C': [4,10,3,5,4,5,3,7,1]}) 
>> 
    A B C 
0 1 6 4 
1 2 8 10 
2 3 8 3 
3 4 4 5 
4 5 2 4 
5 6 1 5 
6 7 1 3 
7 8 2 7 
8 9 8 1 

我想选择其中的一些不平凡函数返回true,例如所有行f(a,c,L),其中L是列表列表,f返回True如果a和c不是同一个子列表的一部分。 也就是说,如果L = [[1,2,3],[4,2,10],[8,7,5,6,9]我想:

A B C 
0 1 6 4 
3 4 4 5 
4 5 2 4 
6 7 1 3 
8 9 8 1 

谢谢!

回答

1

这里是一个非常非常 hacky和非优雅的解决方案。作为另一个免责声明,因为如果列中的数字不在任何子列表中,您的问题没有说明您想要执行的操作,除了isin()中的任何默认功能之外,此代码不会以任何实际方式处理该问题。

import pandas as pd 

df = pd.DataFrame({'A': [1,2,3,4,5,6,7,8,9], 
       'B': [6,8,8,4,2,1,1,2,8], 
       'C': [4,10,3,5,4,5,3,7,1]}) 

L = [[1,2,3],[4,2,10],[8,7,5,6,9]] 


df['passed1'] = df['A'].isin(L[0]) 
df['passed2'] = df['C'].isin(L[0]) 
df['1&2'] = (df['passed1']^df['passed2']) 

df['passed4'] = df['A'].isin(L[1]) 
df['passed5'] = df['C'].isin(L[1]) 
df['4&5'] = (df['passed4']^df['passed5']) 

df['passed7'] = df['A'].isin(L[2]) 
df['passed8'] = df['C'].isin(L[2]) 
df['7&8'] = (df['passed7']^df['passed8']) 

df['PASSED'] = df['1&2'] & df['4&5']^df['7&8'] 

del df['passed1'], df['passed2'], df['1&2'], df['passed4'], df['passed5'], df['4&5'], df['passed7'], df['passed8'], df['7&8'] 
df = df[df['PASSED'] == True] 
del df['PASSED'] 

,看起来像一个输出:

A B C 
0 1 6 4 
3 4 4 5 
4 5 2 4 
6 7 1 3 
8 9 8 1 

我实现了这个码的这个相当快,因此在彻底和完整的丑陋,但我相信你可以重构它任何你想要的方式(例如,用for sub_list in L迭代原始的列表集合,改进变量名称,提出更好的解决方案等)。

希望这会有所帮助。哦,我有没有提到这是不好的代码?因为它是。

+0

谢谢!我确实有自己的解决方案(添加列或明确迭代索引),它们确实不那么优雅。我想知道是否有一些很好的解决方案可以采用该功能并优雅地进行操作。 – ScienceFriction

+0

我想你总是可以定义一个函数'f',它接受列'A',列'C'和列'L'的参数,然后'将其应用到你的数据帧中。请参阅 - > http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.apply.html –