将嵌套的pandas数据框作为列分解出来,并为其每一行重复父行

时间:2014-04-12 10:03:00

标签: python pandas dataframe

我有一个pandas DataFrame基本上类似于这样的东西:

import json
import pandas as pd

df = pd.DataFrame([
    {'a': 1,  'b': 2,  'extra': 0},
    {'a': 10, 'b': 20, 'extra': 0}
])

df_c1 = pd.io.json.read_json(json.dumps({'row1': {'c1': -1, 'c2': -2}}))

df_c2 = pd.io.json.read_json(json.dumps({
    'row1': {'c1': -10,   'c2': -20},
    'row2': {'c1': -100,  'c2': -200},
    'row3': {'c1': -1000, 'c2': -2000}
}))

df['c'] = [df_c1.T, df_c2.T]

我想找到一个格式如下的那个:

例如:

goal = pd.concat([
    pd.DataFrame({'row1': {'a': 1,  'b': 2,  'c1': -1,    'c2': -2}}).T,
    pd.DataFrame({'row1': {'a': 10, 'b': 20, 'c1': -10,   'c2': -20}}).T,
    pd.DataFrame({'row2': {'a': 10, 'b': 20, 'c1': -100,  'c2': -200}}).T,
    pd.DataFrame({'row3': {'a': 10, 'b': 20, 'c1': -1000, 'c2': -2000}}).T
])

In [1]: goal
Out[1]:
       a   b    c1    c2
row1   1   2    -1    -2
row1  10  20   -10   -20
row2  10  20  -100  -200
row3  10  20 -1000 -2000

[4 rows x 4 columns]

有几点需要注意:

  • 索引与c列数据框中相应行的索引匹配
  • 我只想包含['a', 'b']'extra'已被删除
  • df中的第二行3的值为df['c'],因此,其ab值重复3次,对c
  • 中的每一行进行一次
  • 如果它更容易,我可以更改行:df['c'] = [df_c1.T, df_c2.T]不再包含转置:df['c'] = [df_c1, df_c2],但源数据必须是所示格式的JSON。

我当前的解决方案(或多或少)是迭代原始列'c'中的每个元素,然后在切割我想要保留的列时与其父行进行连接。我将此数据框附加到列表中,然后在所有数据框的列表上执行最终pd.concat

它既缓慢又令人作呕,但它确实有效。我喜欢拥有更快更优雅的东西。

1 个答案:

答案 0 :(得分:1)

我不知道为什么要创建一个每个元素都是数据帧的列。但您可以使用pandas.concatpandas.merge来完成这项工作:

# your setup code here
df2 = pd.concat(df['c'].tolist(), keys=df.index)
df3 = pd.merge(df[["a", "b"]], df2, left_index=True, right_on=df2.index.get_level_values(0))
df4 = df3.drop("key_0", axis=1).reset_index(level=0, drop=True)
print df4

这是输出:

       a   b    c1    c2
row1   1   2    -1    -2
row1  10  20   -10   -20
row2  10  20  -100  -200
row3  10  20 -1000 -2000