将列表中的 pandas 数据框列展平到它们自己的特定列
Flatten pandas dataframe column from list to their own specific column
我有一个 pandas 数据框,其中有一列包含内部信息的数组列表。它看起来像这样:
id basket date
c1 [{'product_id': 'P64', 'price': 1146}] 2020-08-11
c2 [{'product_id': 'P44', 'price': 1426}, 2020-08-11
{'product_id': 'P49', 'price': 1108}]
c3 [{'product_id': 'P60', 'price': 39}, 2020-08-11
{'product_id': 'P49', 'price': 1155},
{'product_id': 'P46', 'price': 178}]
我想将篮子列展平,使其看起来像这样:
id product_id price date
c1 P64 1146 2020-08-11
c2 P44 1426 2020-08-11
c2 P49 1108 2020-08-11
c3 P60 39 2020-08-11
c3 P49 1155 2020-08-11
c3 P46 178 2020-08-11
我似乎无法弄清楚,如有任何帮助,我们将不胜感激。
Split (explode) pandas dataframe string entry to separate rows 有爆炸功能,很棒。
def explode(df, lst_cols, fill_value='', preserve_index=False):
# make sure `lst_cols` is list-alike
if (lst_cols is not None
and len(lst_cols) > 0
and not isinstance(lst_cols, (list, tuple, np.ndarray, pd.Series))):
lst_cols = [lst_cols]
# all columns except `lst_cols`
idx_cols = df.columns.difference(lst_cols)
# calculate lengths of lists
lens = df[lst_cols[0]].str.len()
# preserve original index values
idx = np.repeat(df.index.values, lens)
# create "exploded" DF
res = (pd.DataFrame({
col:np.repeat(df[col].values, lens)
for col in idx_cols},
index=idx)
.assign(**{col:np.concatenate(df.loc[lens>0, col].values)
for col in lst_cols}))
# append those rows that have empty lists
if (lens == 0).any():
# at least one list in cells is empty
res = (res.append(df.loc[lens==0, idx_cols], sort=False)
.fillna(fill_value))
# revert the original index order
res = res.sort_index()
# reset index if requested
if not preserve_index:
res = res.reset_index(drop=True)
return res
你会打电话给
explode(df, ['basket'], fill_value='')
那么你必须将键和值拆分到单独的列中,这
这样做。
尝试:
x = [pd.DataFrame(i) for i in df['basket']]
for idx, data in enumerate(x):
data['id']=df.iloc[idx]['id']
data['date']=df.iloc[idx]['date']
df2 = pd.concat(x).reset_index(drop=True)
df2:
product_id price id date
0 P64 1146 c1 2020-08-11
1 P44 1426 c2 2020-08-11
2 P49 1108 c2 2020-08-11
3 P60 39 c3 2020-08-11
4 P49 1155 c3 2020-08-11
5 P46 178 c3 2020-08-11
您可以使用:
import pandas
from pandas import json_normalize
combined = pandas.concat([json_normalize(df['basket']) for column in df])
内联 for 循环为列篮中的每个键创建一个对象列表。然后,使用 pandas.concat,每个列表连接在一个数据帧中,然后 returns 将其合并。
我用它来展平 MongoDb 查询结果。之后你必须添加其他列。
我有一个 pandas 数据框,其中有一列包含内部信息的数组列表。它看起来像这样:
id basket date
c1 [{'product_id': 'P64', 'price': 1146}] 2020-08-11
c2 [{'product_id': 'P44', 'price': 1426}, 2020-08-11
{'product_id': 'P49', 'price': 1108}]
c3 [{'product_id': 'P60', 'price': 39}, 2020-08-11
{'product_id': 'P49', 'price': 1155},
{'product_id': 'P46', 'price': 178}]
我想将篮子列展平,使其看起来像这样:
id product_id price date
c1 P64 1146 2020-08-11
c2 P44 1426 2020-08-11
c2 P49 1108 2020-08-11
c3 P60 39 2020-08-11
c3 P49 1155 2020-08-11
c3 P46 178 2020-08-11
我似乎无法弄清楚,如有任何帮助,我们将不胜感激。
Split (explode) pandas dataframe string entry to separate rows 有爆炸功能,很棒。
def explode(df, lst_cols, fill_value='', preserve_index=False):
# make sure `lst_cols` is list-alike
if (lst_cols is not None
and len(lst_cols) > 0
and not isinstance(lst_cols, (list, tuple, np.ndarray, pd.Series))):
lst_cols = [lst_cols]
# all columns except `lst_cols`
idx_cols = df.columns.difference(lst_cols)
# calculate lengths of lists
lens = df[lst_cols[0]].str.len()
# preserve original index values
idx = np.repeat(df.index.values, lens)
# create "exploded" DF
res = (pd.DataFrame({
col:np.repeat(df[col].values, lens)
for col in idx_cols},
index=idx)
.assign(**{col:np.concatenate(df.loc[lens>0, col].values)
for col in lst_cols}))
# append those rows that have empty lists
if (lens == 0).any():
# at least one list in cells is empty
res = (res.append(df.loc[lens==0, idx_cols], sort=False)
.fillna(fill_value))
# revert the original index order
res = res.sort_index()
# reset index if requested
if not preserve_index:
res = res.reset_index(drop=True)
return res
你会打电话给
explode(df, ['basket'], fill_value='')
那么你必须将键和值拆分到单独的列中,这
尝试:
x = [pd.DataFrame(i) for i in df['basket']]
for idx, data in enumerate(x):
data['id']=df.iloc[idx]['id']
data['date']=df.iloc[idx]['date']
df2 = pd.concat(x).reset_index(drop=True)
df2:
product_id price id date
0 P64 1146 c1 2020-08-11
1 P44 1426 c2 2020-08-11
2 P49 1108 c2 2020-08-11
3 P60 39 c3 2020-08-11
4 P49 1155 c3 2020-08-11
5 P46 178 c3 2020-08-11
您可以使用:
import pandas
from pandas import json_normalize
combined = pandas.concat([json_normalize(df['basket']) for column in df])
内联 for 循环为列篮中的每个键创建一个对象列表。然后,使用 pandas.concat,每个列表连接在一个数据帧中,然后 returns 将其合并。 我用它来展平 MongoDb 查询结果。之后你必须添加其他列。