Python 3.x 如何使用python组合数据帧中的不同列

Python 3.x 如何使用python组合数据帧中的不同列,python-3.x,pandas,numpy,nan,string-concatenation,Python 3.x,Pandas,Numpy,Nan,String Concatenation,假设一个数据帧包含 attacker_1 attacker_2 attacker_3 attacker_4 Lannister nan nan nan nan Stark greyjoy nan 攻击者\u 1攻击者\u 2攻击者\u 3攻击者\u 4 南兰尼斯特酒店 纳斯塔克·格雷乔伊·纳恩 我想创建另一个名为AttackerCombo的列,它将4列聚合为1列。 我将如何在python中定义这样的代码? 我一直在练习p

假设一个数据帧包含

attacker_1 attacker_2 attacker_3 attacker_4 Lannister nan nan nan nan Stark greyjoy nan 攻击者\u 1攻击者\u 2攻击者\u 3攻击者\u 4 南兰尼斯特酒店 纳斯塔克·格雷乔伊·纳恩 我想创建另一个名为AttackerCombo的列,它将4列聚合为1列。 我将如何在python中定义这样的代码? 我一直在练习python,我认为这种列表理解是有意义的,但是[list(x)for x in攻击者] 其中攻击者是一个由4列组成的numpy数组,显示所有4列聚合为1列,但我也要删除所有的NAN。 因此,每行的结果不是 starknannanlannister
StarkAnnanLanister看起来像stark/lannister

您可以在数据框中设置一个新列,通过lambda函数填充该列:

stark/lannister
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)
我认为您需要通过以下方式加入
并删除
NaN

如果需要分隔符
空字符串,请使用:

另外两个解决方案具有
列表理解功能
-首先通过比较,然后检查
字符串

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

有没有一种方法可以使用numpy计算类似的操作,让我们假设dataframe被转换为numpy。还有什么其他可能的理解功能可以使用。谢谢我试图修改@NLASSUX提供的命令battledf['attacker_1','attacker_2','attacker_3','attacker_4']].fillna('').apply(lambda x:'{}{}{}{}}.format(x[0],x[1],x[2],x[3]),axis=1.unique()。这确实产生了一个相关的解决方案。但是我不确定这是不是一个最优的格式,因为它直接调用C代码,所以我们知道它是最优的。另外,.apply()速度很快,但没有pandas内置的并行方法快。完美的解决方案!谢谢您是否可以按照文档中的说明,在“axis”行上展开?如果axis=0,则函数应用于列,如果axis=1,则函数应用于行,您是否可以解释它是如何工作的?正如您在注释中所说的那样。你可以通过
df['attacker_1','attacker_2','attacker_3','attacker_4']]来测试它。apply(打印)
df['attacker_1','attacker_2','attacker_3','attacker_4']]。apply(打印,axis=1)
让我试着解释一下到目前为止我所知道的情况,当我从4列中选取一个子集,并使用apply应用函数时,然后,“lambda x”是子集中所有行上的一个iterable,这里应用的函数是“字符串”/”,与每行上应用的dropna连接,使用axis=1指定。这是正确的还是我遗漏了什么?你能建议同一个手术的一些细微差别吗?例如,在列表理解中,我想到的是查看一行中的每个元素,检查其是否为NaN,然后将非NaN添加到列表中。这可能会解决一些性能障碍的问题。我添加了另外两个解决方案,我希望它们更快。
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
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