2017-01-04 23 views
1

假设一个数据帧包含如何不同列中数据帧用理解的Python

attacker_1 attacker_2 attacker_3 attacker_4 
Lannister nan   nan   nan 
nan   Stark  greyjoy  nan 

我想创建一个名为AttackerCombo另一列是聚合了4列到1列结合起来。 我将如何去在python中定义这样的代码? 我已经练习Python和我认为这种列表解析是有意义的,但[列表(x),用于在攻击者X] 其中攻击者是4列的numpy的阵列显示所有4列聚集成1列,但是我想删除所有的nans。 因此,对于每一行,而不是看起来像

starknannanlannister
结果会是什么样子
stark/lannister

回答

0

我想你需要applyjoin和删除NaN通过dropna

df['attackers'] = df[['attacker_1','attacker_2','attacker_3','attacker_4']] \ 
        .apply(lambda x: '/'.join(x.dropna()), axis=1) 
print (df) 
    attacker_1 attacker_2 attacker_3 attacker_4  attackers 
0 Lannister  NaN  NaN   NaN  Lannister 
1  NaN  Stark greyjoy   NaN Stark/greyjoy 

如果需要separator空字符串使用DataFrame.fillna

df['attackers'] = df[['attacker_1','attacker_2','attacker_3','attacker_4']].fillna('') \ 
        .apply(''.join, axis=1) 
print (df) 
    attacker_1 attacker_2 attacker_3 attacker_4  attackers 
0 Lannister  NaN  NaN   NaN  Lannister 
1  NaN  Stark greyjoy   NaN Starkgreyjoy 

另2个解决方案list comprehension - 首先由notnull比较和第二次检查,如果string

df['attackers'] = df[['attacker_1','attacker_2','attacker_3','attacker_4']] \ 
        .apply(lambda x: '/'.join([e for e in x if pd.notnull(e)]), axis=1) 
print (df) 
    attacker_1 attacker_2 attacker_3 attacker_4  attackers 
0 Lannister  NaN  NaN   NaN  Lannister 
1  NaN  Stark greyjoy   NaN Stark/greyjoy 


#python 3 - isinstance(e, str), python 2 - isinstance(e, basestring) 
df['attackers'] = df[['attacker_1','attacker_2','attacker_3','attacker_4']] \ 
        .apply(lambda x: '/'.join([e for e in x if isinstance(e, str)]), axis=1) 
print (df) 
    attacker_1 attacker_2 attacker_3 attacker_4  attackers 
0 Lannister  NaN  NaN   NaN  Lannister 
1  NaN  Stark greyjoy   NaN Stark/greyjoy 
+0

完美解决方案!谢谢。如果轴= 0,则在列应用功能上的“轴”的线可以展开,按照文件,如果= 1,那么它是在该行申请轴,就可以解释如何在这里工作? –

+0

就像您在评论中所说的一样。您可以通过'DF [ 'attacker_1', 'attacker_2', 'attacker_3', 'attacker_4']]进行测试。适用(打印)'和'DF [ 'attacker_1', 'attacker_2', 'attacker_3',” attacker_4']]。apply(print,axis = 1)' – jezrael

+0

让我试着解释我迄今为止所知道的,当我使用4列的子集并使用apply来应用函数时,'lambda x'是可迭代子集中的所有行,这里应用的函数是'一个字符串“/”与在每行上应用的dropna连接,并且这是使用axis = 1指定的。这是正确的还是我错过了什么 –

0

您可以在数据帧的新列,你将填补由于lambda函数:

df['attackers'] = df[['attacker_1','attacker_2','attacker_3','attacker_4']].apply(lambda x : '{}{}{}{}'.format(x[0],x[1],x[2],x[3]), axis=1) 

你不”牛逼指定如何希望它们聚集,因此,举例来说,如果你想用破折号分开:

df['attackers'] = df[['attacker_1','attacker_2','attacker_3','attacker_4']].apply(lambda x : '{}-{}-{}-{}'.format(x[0],x[1],x[2],x[3]), axis=1) 
+0

是否有WA y使用numpy计算类似的操作,假设数据帧转换为numpy。还有什么可以使用的其他可能的理解功能。谢谢 –

+0

我试图修改命令@nlassaux提供,battledf [ 'attacker_1', 'attacker_2', 'attacker_3', 'attacker_4'] fillna( '')。应用(拉姆达X:“{} { (x [0],x [1],x [2],x [3]),axis = 1).unique()。这确实产生了相关的解决方案。但是我不知道这是否是一个最优 –

+0

格式被称为是最佳的,因为它直接调用C代码。另外,.apply()速度很快,但并不像熊猫的并行方法那么快。 – nlassaux

相关问题