Pandas - 将列值组合到新列中的列表中

clg*_*lg4 12 python lambda list apply pandas

我有一个Python Pandas数据帧df:

d=[['hello',1,'GOOD','long.kw'],
   [1.2,'chipotle',np.nan,'bingo'],
   ['various',np.nan,3000,123.456]]                                                    
t=pd.DataFrame(data=d, columns=['A','B','C','D']) 
Run Code Online (Sandbox Code Playgroud)

看起来像这样:

print(t)
         A         B     C        D
0    hello         1  GOOD  long.kw
1      1.2  chipotle   NaN    bingo
2  various       NaN  3000  123.456
Run Code Online (Sandbox Code Playgroud)

我想创建一个新的列是一个list中值的A,B,C,和D.所以它看起来像这样:

t['combined']                                             

Out[125]: 
0        [hello, 1, GOOD, long.kw]
1        [1.2, chipotle, nan, bingo]
2        [various, nan, 3000, 123.456]
Name: combined, dtype: object
Run Code Online (Sandbox Code Playgroud)

我正在尝试这段代码:

t['combined'] = t.apply(lambda x: list([x['A'],
                                        x['B'],
                                        x['C'],
                                        x['D']]),axis=1)    
Run Code Online (Sandbox Code Playgroud)

哪个返回此错误:

ValueError: Wrong number of items passed 4, placement implies 1 
Run Code Online (Sandbox Code Playgroud)

让我感到困惑的是,如果删除我想要放入列表中的一列(或者将另一列添加到我不添加到列表中的数据帧),我的代码就可以了.

例如,运行以下代码:

t['combined'] = t.apply(lambda x: list([x['A'],
                                        x['B'],
                                        x['D']]),axis=1)      
Run Code Online (Sandbox Code Playgroud)

如果我只想要3列,则返回这是完美的:

print(t)
         A         B     C        D                 combined
0    hello         1  GOOD  long.kw      [hello, 1, long.kw]
1      1.2  chipotle   NaN    bingo   [1.2, chipotle, bingo]
2  various       NaN  3000  123.456  [various, nan, 123.456]
Run Code Online (Sandbox Code Playgroud)

我完全不知道为什么请求数据框中所有列的"组合"列表会产生错误,但是选择除1列以外的所有列来创建"组合"列表并按预期创建列表.

Ste*_*n G 17

试试这个 :

t['combined']= t.values.tolist()

t
Out[50]: 
         A         B     C        D                       combined
0    hello         1  GOOD  long.kw      [hello, 1, GOOD, long.kw]
1     1.20  chipotle   NaN    bingo    [1.2, chipotle, nan, bingo]
2  various       NaN  3000   123.46  [various, nan, 3000, 123.456]
Run Code Online (Sandbox Code Playgroud)

  • @pedjjj `t[cols].values.tolist()` (12认同)
  • 无论如何,在每一行中都有获得nan价值的机会吗? (3认同)

cot*_*ail 5

另一种方法是调用list()底层 numpy 数组

t['combined_arr'] = list(t.values)
Run Code Online (Sandbox Code Playgroud)

应该注意的是,这会产生与使用略有不同的列.tolist()。从下面可以看出,tolist()创建一个嵌套列表,同时list()创建一个数组列表。

t['combined_list'] = t[['A', 'B']].values.tolist()
t['combined_arr'] = list(t[['A', 'B']].values)

t.iloc[0, 4]  # ['hello', 1]
t.iloc[0, 5]  # array(['hello', 1], dtype=object)
Run Code Online (Sandbox Code Playgroud)

根据用例,保留 ndarray 类型有时很有用。


如果要合并没有NaN 值的列,那么最快的方法是在检查 NaN 值时循环遍历行。作为NaN!=NaN,最快的检查是检查一个值是否等于其自身。

t['combined'] = [[e for e in row if e==e] for row in t.values.tolist()]


         A     B     C        D                     combined
0    hello   1.0  GOOD  long.kw  [hello, 1.0, GOOD, long.kw]
1      1.2  10.0   NaN    bingo           [1.2, 10.0, bingo]  <-- no NaN
2  various   NaN  3000  123.456     [various, 3000, 123.456]  <-- no NaN
Run Code Online (Sandbox Code Playgroud)

更完整的检查是使用isnan内置math模块。

import math
t['combined'] = [[e for e in row if not (isinstance(e, float) and math.isnan(e))] for row in t.values.tolist()]
Run Code Online (Sandbox Code Playgroud)

要合并特定列的非 NaN 值,请先选择这些列:

cols = ['A', 'B']
t['combined'] = [[e for e in row if e==e] for row in t[cols].values.tolist()]
Run Code Online (Sandbox Code Playgroud)