[英]Unpacking dataframe column with list values
假設我們在下面有df_orig
,其中B
列包括不同長度的列表作為行。 在B
每一行中, X
的值都是唯一的。 X
每個唯一值可能會也可能不會出現在B
每一行中。 我認為這個例子解釋得最好。
import pandas as pd
df_orig = pd.DataFrame({
'A': ['a', 'b', 'c', 'd', 'e'],
'B': [
[{'X': 'abc'}],
[{'X': 'abc'}, {'X': 'dtf'}, {'X': 'kju'}],
[{'X': 'abc'}, {'X': 'dtf'}],
[{'X': 'abc'}, {'X': 'dtf'}, {'X': 'kju'}, {'X': 'etr'}],
[]
]
})
df_orig
A B
0 a [{'X': 'abc'}]
1 b [{'X': 'abc'}, {'X': 'dtf'}, {'X': 'kju'}]
2 c [{'X': 'abc'}, {'X': 'dtf'}]
3 d [{'X': 'abc'}, {'X': 'dtf'}, {'X': 'kju'}, {'X': 'etr'}]
4 e []
我想要的是“解包” B
以便X
每個唯一值都有自己的列,使用0/1
編碼指示該值(列名)是否存在於每一行中。 所需的dataframe
df_des
如下所示:
df_des
A abc dtf kju etr
0 a 1 0 0 0
1 b 1 1 1 0
2 c 1 1 0 0
3 d 1 1 1 1
4 e 0 0 0 0
您可以使用數據框構造函數並使用applymap
、 get_dummies
和join
返回每個單元格中字典的值:
m = (pd.DataFrame(df_orig['B'].tolist()).applymap(lambda x:
[*x.values()][0] if isinstance(x,dict) else x))
final = df_orig[['A']].join(
pd.get_dummies(m).groupby(lambda x: x.split('_')[-1],axis=1).max())
編輯:要加入多個列,您可以pop
列B
並加入如下所示:
m = (pd.DataFrame(df_orig.pop('B').tolist()).applymap(lambda x:
[*x.values()][0] if isinstance(x,dict) else x))
final = df_orig.join(
pd.get_dummies(m).groupby(lambda x: x.split('_')[-1],axis=1).max())
A abc dtf etr kju
0 a 1 0 0 0
1 b 1 1 0 1
2 c 1 1 0 0
3 d 1 1 1 1
4 e 0 0 0 0
另一種方法:
#extract the data from the dictionary
df_orig['C'] = df_orig.B.apply(lambda x: [i['X'] for i in x])
#convert list to string
df_orig.C = df_orig.C.apply(lambda x: ','.join(x))
create dummies from split string
dum = pd.get_dummies(df_orig.C.str.split(',', expand=True)).drop('0_',axis=1)
#strip numbers off the columns
dum.columns = dum.columns.str.replace('\d_','')
#join dummies back to parent dataframe
pd.concat([df_orig['A'], dum], axis=1).filter(['A','abc','dtf','etr','kju'])
A abc dtf etr kju
0 a 1 0 0 0
1 b 1 1 0 1
2 c 1 1 0 0
3 d 1 1 1 1
4 e 0 0 0 0
你去吧:
import pandas as pd
from sklearn.preprocessing import MultiLabelBinarizer
df_orig = pd.DataFrame({
'A': ['a', 'b', 'c', 'd', 'e'],
'B': [
[{'X': 'abc'}],
[{'X': 'abc'}, {'X': 'dtf'}, {'X': 'kju'}],
[{'X': 'abc'}, {'X': 'dtf'}],
[{'X': 'abc'}, {'X': 'dtf'}, {'X': 'kju'}, {'X': 'etr'}],
[]
]
})
b = []
for x in df_orig.B:
dummy = []
for y in x:
dummy.append(y['X'])
b.append(dummy)
b = pd.Series(b)
mlb = MultiLabelBinarizer()
res = pd.DataFrame(mlb.fit_transform(b),columns=mlb.classes_,index=b.index)
df_orig = df_orig.drop(['B'],axis=1)
df_res = pd.concat([df_orig,res],axis=1)
print(df_res)
output:
A abc dtf etr kju
0 a 1 0 0 0
1 b 1 1 0 1
2 c 1 1 0 0
3 d 1 1 1 1
4 e 0 0 0 0
首先,將 B 列設為列表列表,然后使用 multilabelbinarizer 對列表列表進行單熱編碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.