繁体   English   中英

pandas:来自dict的数据帧,以逗号分隔的值

[英]pandas: dataframe from dict with comma separated values

我正在尝试从嵌套字典创建一个DataFrame,其中值以逗号分隔的字符串。

每个值都嵌套在一个dict中,例如:

dict = {"1":{
             "event":"A, B, C"},
        "2":{
             "event":"D, B, A, C"},
        "3":{
             "event":"D, B, C"}
        }

我想要的输出是:

    A   B   C   D
0   A   B   C   NaN
1   A   B   C   D
2   NaN B   C   D

到目前为止我所有人都将dict转换为dataframe并拆分每个列表中的项目。 但我不确定这是否让我更接近我的目标。

df = pd.DataFrame(dict)
Out[439]: 
           1           2        3
event  A, B, C  D, B, A, C  D, B, C

In [441]: df.loc['event'].str.split(',').apply(pd.Series)                                                                                                                                                                                 
Out[441]: 
   0   1   2    3
1  A   B   C  NaN
2  D   B   A    C
3  D   B   C  NaN

任何帮助表示赞赏。 谢谢

您可以使用一些理解来按摩嵌套的dict,以更好的格式创建DataFrame,以标记列的条目是否存在:

the_dict = {"1":{
             "event":"A, B, C"},
        "2":{
             "event":"D, B, A, C"},
        "3":{
             "event":"D, B, C"}
        }

df = pd.DataFrame([[{z:1 for z in y.split(', ')} for y in x.values()][0] for x in the_dict.values()])
>>> df

     A  B  C    D
0  1.0  1  1  NaN
1  1.0  1  1  1.0
2  NaN  1  1  1.0

一旦你创建了DataFrame,你就可以简单地循环遍历列并使用where方法将标记字母存在的值转换为字母(下面这样做NaN离开为NaN,否则它会插入列​​的字母):

for col in df.columns:
    df_mask = df[col].isnull()
    df[col]=df[col].where(df_mask,col)
>>> df

     A  B  C    D
0    A  B  C  NaN
1    A  B  C    D
2  NaN  B  C    D

根据@ merlin的建议,您可以直接理解答案:

df = pd.DataFrame([[{z:z for z in y.split(', ')} for y in x.values()][0] for x in the_dict.values()])
>>> df
     A  B  C    D
0    A  B  C  NaN
1    A  B  C    D
2  NaN  B  C    D

根据你所拥有的(修改了一点点拆分以pd.crosstab()额外的空格) df1 ,你可以只是stack结果并在索引和值列上使用pd.crosstab()

df1 = df.loc['event'].str.split('\s*,\s*').apply(pd.Series) 

df2 = df1.stack().rename('value').reset_index()
pd.crosstab(df2.level_0, df2.value)

#   value   A   B   C   D
# level_0               
#       1   1   1   1   0
#       2   1   1   1   1
#       3   0   1   1   1

这并不像你要求的那样,但我想你可能更喜欢这个你想要的输出。

要准确获取所需内容,可以添加一个额外的列,该列等于上面的值列,然后取消堆栈包含值的索引:

df2 = df1.stack().rename('value').reset_index()
df2['value2'] = df2.value
df2.set_index(['level_0', 'value']).drop('level_1', axis = 1).unstack(level = 1)

#         value2
#   value   A     B     C     D
# level_0               
#       1   A     B     C  None
#       2   A     B     C     D
#       3   None  B     C     D

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM