我有一个类似以下的数据集:
import pandas as pd
df = pd.DataFrame([[[{'name': 'Joe', 'age': 32, 'category': 'A'}, {'name': 'Jane', 'age': 35, 'category': 'A'}]],
[[{'name': 'Beth', 'age': 33, 'category': 'B'}, {'name': 'Bob', 'age': 32, 'category': 'B'}]],
[[{'name': 'John', 'age': 35, 'category': 'C'}]],
[[{'name': 'Jill', 'age': 33, 'category': 'D'}]],
], columns=['Entries'])
数据框只有一列(称为“条目”),其中每一行都包含一个或多个词典的列表。
我需要一种方法来将字典中每个键的数据帧转换为一列,并使值显示在那些对应的列中,如下所示:
age category name
0 32.0 A Joe
1 35.0 A Jane
2 33.0 B Beth
3 32.0 B Bob
4 35.0 C John
5 33.0 D Jill
目前,我有以下代码可以做到这一点:
df2 = pd.DataFrame()
for idx, row in df.iterrows():
for entry in row.Entries:
name = entry['name']
age = entry['age']
category = entry['category']
single_entry = pd.Series({'name': name, 'age': age, 'category': category})
df2 = df2.append(single_entry, ignore_index=True)
上面的代码可以正常工作,但是在我的实际数据集上却非常慢,该数据集有超过1,000,000行。
我考虑过使用内置的Pandas函数来利用它们的速度提升,例如apply函数,但是我不知道如何将其应用于这个特定问题。
什么是达到上述结果的更有效方法?
我建议将列表理解与平坦值一起使用以提高速度:
df = pd.DataFrame([y for x in df['Entries'] for y in x])
另一个想法:
from itertools import chain
df = pd.DataFrame(chain.from_iterable(df['Entries'].tolist()))
print (df)
name age category
0 Joe 32 A
1 Jane 35 A
2 Beth 33 B
3 Bob 32 B
4 John 35 C
5 Jill 33 D
对于4万行,样本数据重复执行10000次的性能:
df = pd.concat([df] * 10000, ignore_index=True)
In [222]: %timeit pd.DataFrame([y for x in df['Entries'] for y in x])
66.1 ms ± 770 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [223]: %timeit pd.DataFrame(chain.from_iterable(df['Entries'].tolist()))
60.9 ms ± 691 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [224]: %timeit pd.DataFrame(itertools.chain(*df.Entries.tolist()))
60.8 ms ± 237 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [225]: %timeit pd.DataFrame(sum(df.Entries.tolist(),[]))
3.94 s ± 18.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [226]: %timeit pd.DataFrame(df['Entries'].explode().tolist())
131 ms ± 3.28 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句