python熊猫通过删除重复项来加入动态列
问题描述:
我们有一个用例,我们需要通过删除重复项来连接一行中的所有列值.Data存储在熊猫的数据框中。 对于例如考虑数据帧DF以下与列A,B,Cpython熊猫通过删除重复项来加入动态列
A B C
X1 AX X1
X2 X2 X1
X3 X3 X3
X4 XX XX
我想其中串接甲一个新列B添加到C和删除重复如果任何通过保留的顺序找到。输出将如
A B C Newcol
X1 AX X1 X1_AX
X2 X2 X1 X2_X1
X3 X3 X3 X3
X4 XX XX X4_XX
请注意,列数是动态的。 截至目前,我通过使用命令
df.apply(lambda x: '-'.join(x.dropna().astype(str).drop_duplicates()),axis=1)
这样做,但这样很慢,需要大约150秒,我的数据。 但由于90%以上的数据帧的通常只有2列,我把一个if语句在我的代码和2列
t1=pd.Series(np.where(df.iloc[:,0].dropna().astype(str) != df.iloc[:,1].dropna().astype(str), df.iloc[:,0].dropna().astype(str)+"-"+df.iloc[:,1].dropna().astype(str),df.iloc[:,1].dropna().astype(str)))
运行情况下面命令,它需要大约55.3毫秒的
甚至
t1=df.iloc[:,0].dropna().astype(str).where(df.iloc[:,0].dropna().astype(str) == df.iloc[:,1].dropna().astype(str), df.iloc[:,0].dropna().astype(str)+"-"+df.iloc[:,1].dropna().astype(str))
既消耗几乎同一时间(55毫秒相对长为150秒),但是问题是它仅适用于2列是适用的。 我想创建一个通用语句,以便它可以处理n个列。 我尝试使用减少顶部,但它给了错误,而我尝试了3列。
reduce((lambda x,y:pd.Series(np.where(df.iloc[:,x].dropna().astype(str) != df.iloc[:,y].dropna().astype(str), df.iloc[:,x].dropna().astype(str)+"-"+df.iloc[:,y].dropna().astype(str),df.iloc[:,y].dropna().astype(str)))),list(range(df.shape[1])))
TypeError: '>=' not supported between instances of 'str' and 'int'
请注意,DF实际上是一个多核并行任务的一大块。如果这些建议不包括并行性,那将会很棒。
答
尝试
df['new'] = df.astype('str').apply(lambda x: '_'.join(set(x)), axis = 1)
A B C new
0 X1 AX X1 AX_X1
1 X2 X2 X1 X1_X2
2 X3 X3 X3 X3
3 X4 XX XX X4_XX
编辑:保持列的顺序值
def my_append(x):
l = []
for elm in x:
if elm not in l:
l.append(elm)
return '_'.join(l)
df['New col']=df.astype('str').apply(my_append, axis = 1)
1000 loops, best of 3: 871 µs per loop
返回
A B C New col
0 X1 AX X1 X1_AX
1 X2 X2 X1 X2_X1
2 X3 X3 X3 X3
3 X4 XX XX X4_XX
编辑1:如果您有男在任一列这样
A B C
0 X1 AX X1
1 X2 X2 X1
2 X3 X3 X3
3 NaN XX XX
手柄,在功能,然后应用
def my_append(x):
l = []
for elm in x:
if elm not in l:
l.append(elm)
l = [x for x in l if str(x) != 'nan']
return '_'.join(l)
df['New col']=df.astype('str').apply(my_append, axis = 1)
A B C New col
0 X1 AX X1 X1_AX
1 X2 X2 X1 X2_X1
2 X3 X3 X3 X3
3 NaN XX XX XX
答
pd.unique
不排序。用它包裹在一个修真
df.assign(new_col=['_'.join(pd.unique(row)) for row in df.values])
A B C new_col
0 X1 AX X1 X1_AX
1 X2 X2 X1 X2_X1
2 X3 X3 X3 X3
3 X4 XX XX X4_XX
手柄的NaN
df.assing(new_col=[
'_'.join(pd.unique([i for i in row if pd.notnull(i)])) for row in df.values
])
抱歉,但正如我所说,我需要保持秩序。设置键。指数设置给出了错误,并没有太多的时间收益要么 – niths4u
是的,我注意到,后来,请参阅编辑 – Vaishali
哇。这确实起到了诀窍,新代码只需要2秒,而150秒。谢谢。有一个疑问。那么dropna()呢?不应该一起添加吗? – niths4u