需要一种有效的方法来从json对象生成器创建一个数据帧吗?

时间:2019-10-11 23:22:39

标签: python pandas

我有一个发电机:

gen = ([{'Key': x, 'Data': {'value': i}} for i in range(3)] for x in ['A', 'B', 'C'])

我想以以下形式创建一个数据框:

df = pd.DataFrame([
    {'Key': 'A', 'Data': 0},
    {'Key': 'A', 'Data': 1},
    {'Key': 'A', 'Data': 2},
    {'Key': 'B', 'Data': 0},
    {'Key': 'B', 'Data': 1},
    {'Key': 'B', 'Data': 2},
    {'Key': 'C', 'Data': 0},
    {'Key': 'C', 'Data': 1},
    {'Key': 'C', 'Data': 2},
])

有没有更有效的方法?

final_df = pd.DataFrame()
for x in gen:
    df = pd.DataFrame(x)
    df['Data'] = df['Data'].apply(lambda x: x['value'])
    final_df = pd.concat([final_df, df])

final_df.reset_index()

4 个答案:

答案 0 :(得分:2)

我会使用pd.io.json.json_normalizefrom_iterable

from itertools import chain

>>> df = pd.io.json.json_normalize(chain.from_iterable(gen))

  Key  Data.value
0   A           1
1   A           2
2   B           0
3   B           1
4   B           2
5   C           0
6   C           1
7   C           2

答案 1 :(得分:1)

您可以使用列表推导,然后分配列名。

>>> pd.DataFrame([(key, data) for key in 'ABC' for data in range(3)], 
                 columns=['Key', 'Data'])
  Key  Data
0   A     0
1   A     1
2   A     2
3   B     0
4   B     1
5   B     2
6   C     0
7   C     1
8   C     2

# Or using a generator instead of a list comprehension:
pd.DataFrame(((key, data) for key in 'ABC' for data in range(3)], 
              columns=['Key', 'Data'))

答案 2 :(得分:0)

从生成器gen开始,您可以遍历并生成成对(元组)列表。然后制作数据框。

pairs = [(p['Key'], p['Data']['value']) for el in gen for p in el]
df = pd.DataFrame(pairs, columns=['Key', 'Data'])

使用您的gendf

  Key  Data
0   A     0
1   A     1
2   A     2
3   B     0
4   B     1
5   B     2
6   C     0
7   C     1
8   C     2

在我的机器上,这至少比您的解决方案快3倍,至少对于您提供的“短”生成器而言。这个比例可能随着“更长”的发电机而改变。

答案 3 :(得分:0)

在0.25大熊猫中,您可以进行explode

pd.DataFrame(pd.Series(gen).explode().tolist()).assign(Data=lambda x : x['Data'].str.get('value'))
  Key  Data
0   A     0
1   A     1
2   A     2
3   B     0
4   B     1
5   B     2
6   C     0
7   C     1
8   C     2