Python 合并包含列表对象的列
我的问题类似于“”和“”,但由于我要合并的单元格包含列表,所有给定的答案都不起作用 简化后,我的df如下所示:Python 合并包含列表对象的列,python,pandas,numpy,Python,Pandas,Numpy,我的问题类似于“”和“”,但由于我要合并的单元格包含列表,所有给定的答案都不起作用 简化后,我的df如下所示: players players1 players2 players3 1 ['1','2'] 2 ['2','4'] 3 ['1','4'] 4 ['1','5'] 5
players players1 players2 players3
1 ['1','2']
2 ['2','4']
3 ['1','4']
4 ['1','5']
5 ['3','5']
6
7 ['3','4']
(因此我知道其中两列中永远不会有值。)
现在,我想添加一个新的列,其中包含以下列表:
players players1 players2 players3 players_combine
1 ['1','2'] ['1','2']
2 ['2','4'] ['2','4']
3 ['1','4'] ['1','4']
4 ['1','5'] ['1','5']
5 ['3','5'] ['3','5']
6
7 ['3','4'] ['3','4']
我尝试了很多东西——主要是链接答案的变体,我的最后一个想法是级联np。但它不起作用。只有来自“玩家”的值显示在组合列中
df['players_combine'] = np.where(df.players.notnull(),df.players.values,np.where(df.players1.notnull(),df.players1.values,np.where(df.players2.notnull(),df.players2.values,np.where(df.players3.notnull(),df.players3.values,np.nan))))
编辑:
如评论中所述:df.head(5).to_dict()
如果任何空单元格是空字符串(
'
),请首先将其设置为NaN:
df[df==''] = np.nan
然后,选择每行中所有非NAN的最大值:
df.apply(lambda x: x[x.notnull()].max(), axis=1)
#1 [1, 2]
#2 [2, 4]
#3 [1, 4]
#4 [1, 5]
#5 [3, 5]
#6 NaN
#7 [3, 4]
df.loc[df.notnull().any(axis=1)]\
.apply(lambda x: x[x.first_valid_index()], axis=1)
#1 [1, 2]
#2 [2, 4]
#3 [1, 4]
#4 [1, 5]
#5 [3, 5]
#7 [3, 4]
另一个有趣的解决方案(更快)是消除所有NaN行,然后在每行中找到第一个有效值:
df.apply(lambda x: x[x.notnull()].max(), axis=1)
#1 [1, 2]
#2 [2, 4]
#3 [1, 4]
#4 [1, 5]
#5 [3, 5]
#6 NaN
#7 [3, 4]
df.loc[df.notnull().any(axis=1)]\
.apply(lambda x: x[x.first_valid_index()], axis=1)
#1 [1, 2]
#2 [2, 4]
#3 [1, 4]
#4 [1, 5]
#5 [3, 5]
#7 [3, 4]
因为您知道每行最多只能在一列中输入一个值,所以可以用
NaN
替换不关心的值,然后使用.stack
在本例中,您似乎同时拥有'nan'
和'
字符串,这些字符串应首先替换为np.nan
import numpy as np
df['players_combine'] = df.replace({'': np.NaN, 'nan': np.NaN}, regex=True).stack().reset_index(level=1, drop=True)
样本数据
输出:
分析你的
df.to_dict()
看起来,对于某些单元格,你有字符串nan
,对于其他单元格,你有实际的np.nan
,对于其他单元格,你甚至有空字符串'
因此,首先通过统一空值来清理数据集:
df = df.replace({'nan':np.nan, '':np.nan})
然后您可以通过轴=1
df['players_combine'] = df.agg(lambda s: s[~s.isnull()][0], axis=1)
由于一些格式错误的数据是我代码中的问题,而不是问题所在,所以我想添加一些关于所有不同选项性能的信息。我使用了np.where,因为它使用矢量化,而np.apply迭代行,因此存在巨大的性能差异
设置4*2000=8000行的测试df:
import pandas as pd
import numpy as np
l = [[['1','2'],np.NaN,np.NaN,np.NaN],
[np.NaN,['2','3'],np.NaN,np.NaN],
[np.NaN,np.NaN,['3','4'],np.NaN],
[np.NaN,np.NaN,np.NaN,['4','5']]]
l=l*2000
df = pd.DataFrame(l)
df.columns = ['players','players1','players2','players3']
最佳选择:
%timeit df['players_combine'] = np.where(df.players.notnull(),df.players.values,np.where(df.players1.notnull(),df.players1.values,np.where(df.players2.notnull(),df.players2.values,np.where(df.players3.notnull(),df.players3.values,np.nan))))
100 loops, best of 3: 2.18 ms per loop
非常好的选择:
%timeit df.loc[df.notnull().any(axis=1)]\
.apply(lambda x: x[x.first_valid_index()], axis=1)
100 loops, best of 3: 413 ms per loop
其他备选方案1:
%timeit df['players_combine'] = df.agg(lambda s: s[~s.isnull()][0], axis=1)
1 loop, best of 3: 4.71 s per loop
和2:
%timeit df['players_combine'] = df.apply(lambda x: x[x.notnull()].max(), axis=1)
1 loop, best of 3: 4.86 s per loop
您能将df.post
to_dict()
?单元格中不能有“无值”。它们里面到底有什么?空字符串、空列表、N?其他列中的空值是多少?它是一个空字符串,还是NaN,还是一个空列表?如果您发布d=df.to_dict()
,我们只需执行pd.DataFrame(d)
,并按原样复制数据帧:)@J_Scholz然后只需执行df.head(5.to_dict()
)看来“南”一直是我的问题。我把它们当成真正的np.nan。现在是我的np.where行。谢谢,np.where解比这还要快。看看我的答案。
%timeit df['players_combine'] = df.apply(lambda x: x[x.notnull()].max(), axis=1)
1 loop, best of 3: 4.86 s per loop