Pandas DataFrame - 将列转换为JSON并添加为新列

3
考虑以下来自MySQL表的DataFrame,大小为11k行:
col1 |  col2 | col3  | col4
-----------------------------
 cat | black | small | lovely
-----------------------------
 dog | white | medium| brave 
-----------------------------
mice | grey  | tinny | fast

...

我希望你能动态转换成以下内容:

我想将它 动态地 转换为以下内容:

col1 |     newcol
------------------------------------------------------------
 cat | {"col2": "black", "col3": "small", "col4": "lovely"}
------------------------------------------------------------
 dog | {"col2": "white", "col3": "medium", "col4": "brave"}
------------------------------------------------------------
mice | {"col2": "grey", "col3": "tinny", "col4": "fast"}

...

我在这里描述了问题的完整端到端解决方案:https://codeflex.co/mysql-table-migration-with-pandas-dataframe/ - undefined
6个回答

9
你可以在axis=1上将agg处理为dict
对于字典:
out = df[['col1']].assign(new_col=df.iloc[:,1:].agg(dict,1))

对于JSON:

out = df[['col1']].assign(new_col=df.iloc[:,1:].agg(pd.Series.to_json,1))

print(out)

   col1                                            new_col
0   cat  {'col2': 'black', 'col3': 'small', 'col4': 'lo...
1   dog  {'col2': 'white', 'col3': 'medium', 'col4': 'b...
2  mice  {'col2': 'grey', 'col3': 'tinny', 'col4': 'fast'}

1
这绝对是迄今为止最干净的解决方案,我会将这个标记为正确的。 - undefined
看起来不错,但是我怎么才能得到 JSON 而不是字典呢? - undefined
1
@ybonda然后在代码中将dict替换为pd.Series.to_json,就像这样:df[['col1']].assign(new_col=df.iloc[:,1:].agg(pd.Series.to_json,1)),我修改了我的答案。 - undefined

2

正如你所料,有许多方法可以做到这一点,但是我想到的是:

>>> import pandas as pd
>>> d = {"col1": ["cat", 'dog', 'mice'], "col2": ["black", "white", "grey"], "col3": ["small", 'medium', 'tinny'], 'col4': ['lovely', 'brave','fast']}
>>> df = pd.DataFrame(d)
>>> pd.concat([df[['col1']], pd.DataFrame({"newcol": df[['col2','col3','col4']].to_dict(orient='records')})], axis=1)

对于一些你可能不知道DataFrame中想要的列名的情况,可以使用以下方法选择列索引。在这种情况下,从第1列开始,一直到最后。

>>> pd.concat([df[['col1']], pd.DataFrame({"newcol": df.iloc[:, 1:].to_dict(orient='records')})], axis=1)

我有11,000行... 我需要动态地完成它 - undefined

2
使用df.to_json(orient='records')将JSON记录列表转储,然后加载JSON到字典列表中,并分配给新列。
import pandas as pd
df = pd.DataFrame({'col1': ['cat', 'dog', 'mice'], 
        'col2' : ['black', 'white', 'grey'], 
        'col3' : ['small', 'medium', 'tinny']})

# create json column
# data_json = df.iloc[:, 1:].to_json(orient='records')
# data = json.loads(data_json)
data = df.iloc[:, 1:].to_dict(orient='records')

# keep first column
dfn = df.iloc[:, [0]].copy()
dfn['newcol'] = data
# dfn['newcol'] = pd.Series(data).map(json.dumps)

dfn

   col1                               newcol
0   cat   {"col2": "black", "col3": "small"}
1   dog  {"col2": "white", "col3": "medium"}
2  mice    {"col2": "grey", "col3": "tinny"}

data_json(type str)

[{"col2":"black","col3":"small"},{"col2":"white","col3":"medium"},{"col2":"grey","col3":"tinny"}]

1

0

在下面的示例中,我正在使用三列。

data = {'col1': ['cat', 'dog', 'mice'], 'col2' : ['black', 'white', 'grey'], 'col3' : ['small', 'medium', 'tinny']}
import pandas as pd
df = pd.DataFrame(data)
col = list(df.columns)


我们可以使用lambda函数如下所示
df.apply(lambda x: {col[1]:x[1], col[2]:x[2]}, axis =1)

你可以按照以下方式将其添加到数据框中。
df['new_col'] = df.apply(lambda x: {col[1]:x[1], col[2]:x[2]}, axis =1)

这会产生以下输出。
df
   col1   col2    col3                              new_col
0   cat  black   small   {'col2': 'black', 'col3': 'small'}
1   dog  white  medium  {'col2': 'white', 'col3': 'medium'}
2  mice   grey   tinny    {'col2': 'grey', 'col3': 'tinny'}


然后使用df.drop删除不需要的列。
这样应该能得到所需的输出。

df.drop(['col2', 'col3'], axis = 1)
   col1                              new_col
0   cat   {'col2': 'black', 'col3': 'small'}
1   dog  {'col2': 'white', 'col3': 'medium'}
2  mice    {'col2': 'grey', 'col3': 'tinny'}

0

根据给定的要求,我建议使用itertuples生成一个字典列表,并将其分配给数据框,如下所示

import pandas as pd 
data = {'col1': ['cat', 'dog', 'mice'], 'col2' : ['black', 'white', 'grey'], 'col3' : ['small', 'medium', 'tinny'], 'col4': ['lovely','brave','fast']} 
df = pd.DataFrame(data) 

def getDictColumn_df1(df, new_col_name="newcol", cols_from_start=1):
    df[new_col_name] = tuple(map(lambda row: row._asdict(), df.iloc[:,cols_from_start:].itertuples()))
    return df[['col1', new_col_name]]

getDictColumn_df1(df)

想要了解更多关于itertuples()的信息,请点击这里查看。

对于一种稍微不同的情况,当您希望保留所有索引并将所有值转换为一个字典时,您可以这样做:

def getDictColumn_df2(df, new_col_name="newcol"):
    df[new_col_name] = tuple(map(lambda row: row._asdict(), df.itertuples(index=False)))
    return df[[new_col_name]]

getDictColumn_df2(df)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接