Python 3.x 跨列的唯一值(按行排列)缺少值
我有一个像Python 3.x 跨列的唯一值(按行排列)缺少值,python-3.x,pandas,unique,Python 3.x,Pandas,Unique,我有一个像 import pandas as pd import numpy as np df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'], "Col2": ['A', 'B', 'B', 'A', 'C'], "Col3": ['A', 'B', 'C', 'A', 'C']}) 我希望获得每行的跨
import pandas as pd
import numpy as np
df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'],
"Col2": ['A', 'B', 'B', 'A', 'C'],
"Col3": ['A', 'B', 'C', 'A', 'C']})
我希望获得每行的跨列的唯一组合,并使用这些值创建一个新列,排除缺少的值
我现在要做的代码是
def handle_missing(s):
return np.unique(s[s.notnull()])
def unique_across_rows(data):
unique_vals = data.apply(handle_missing, axis = 1)
# numpy unique sorts the values automatically
merged_vals = unique_vals.apply(lambda x: x[0] if len(x) == 1 else '_'.join(x))
return merged_vals
df['Combos'] = unique_across_rows(df)
这将返回预期的输出:
Col1 Col2 Col3 Combos
0 A A A A
1 NaN B B B
2 B B C B_C
3 B A A A_B
4 C C C C
在我看来,熊猫内部应该有一种更为矢量化的方法来实现这一点:我如何才能做到这一点?试试(下面的解释)
输出:
Col1 Col2 Col3 Combos
0 A A A A
1 NaN B B B
2 B B C B_C
3 B A A A_B
4 C C C C
您还可以在轴=1上使用
agg/apply
,如下所示:
df['Combos'] = df.agg(lambda x: '_'.join(sorted(x.dropna().unique())),axis=1)
您可以尝试一种简单的列表理解方法,对于较大的数据帧可能更有效:
df['combos'] = ['_'.join(sorted(k for k in set(v) if pd.notnull(k))) for v in df.values]
或者,您可以将上述列表理解包装在一个更可读的函数中:
def combos():
for v in df.values:
unique = set(filter(pd.notnull, v))
yield '_'.join(sorted(unique))
df['combos'] = list(combos())
用字符串占位符“-”填充nan。从col1、col2、col3列表中创建一个唯一的数组,并删除占位符。将唯一数组值与“-”连接起来
import pandas as pd
import numpy as np
def unique(list1):
if '-' in list1:
list1.remove('-')
x = np.array(list1)
return (np.unique(x))
df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'],
"Col2": ['A', 'B', 'B', 'A', 'C'],
"Col3": ['A', 'B', 'C', 'A', 'C']}).fillna('-')
s="-"
for key,row in df.iterrows():
df.loc[key,'combos']=s.join(unique([row.Col1, row.Col2, row.Col3]))
print(df.head())
在一些较大的数据帧上,列表理解被证明是最快的方法,生成器函数也没有慢多少。
def combos():
for v in df.values:
unique = set(filter(pd.notnull, v))
yield '_'.join(sorted(unique))
df['combos'] = list(combos())
Col1 Col2 Col3 combos
0 A A A A
1 NaN B B B
2 B B C B_C
3 B A A A_B
4 C C C C
import pandas as pd
import numpy as np
def unique(list1):
if '-' in list1:
list1.remove('-')
x = np.array(list1)
return (np.unique(x))
df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'],
"Col2": ['A', 'B', 'B', 'A', 'C'],
"Col3": ['A', 'B', 'C', 'A', 'C']}).fillna('-')
s="-"
for key,row in df.iterrows():
df.loc[key,'combos']=s.join(unique([row.Col1, row.Col2, row.Col3]))
print(df.head())