Python 将函数应用于数据帧的每一行,以便每个条目返回一个或多个新行

Python 将函数应用于数据帧的每一行,以便每个条目返回一个或多个新行,python,pandas,dataframe,lambda,Python,Pandas,Dataframe,Lambda,我的数据集如下所示: 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':

我的数据集如下所示:

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'])
dataframe有一个列(名为“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)
上面的代码工作得很好,但在我的实际数据集上非常慢,它有超过1000000行

我考虑过使用内置的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()))

性能对于40k行,样本数据重复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)


我建议使用列表理解和扁平化值来提高速度:

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()))

性能对于40k行,样本数据重复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)

IIUC

IIUC


如果要保留记录中的索引,explode会有所帮助

s=df['Entries'].explode()
pd.DataFrame(s.tolist(),index=s.index)


如果要保留记录中的索引,explode会有所帮助

s=df['Entries'].explode()
pd.DataFrame(s.tolist(),index=s.index)


@anky_91不用担心,如果你想发布,请继续,因为我换了另一种方法~@anky_91不用担心,如果你想发布,请继续,因为我换了另一种方法~哈哈,我又发布了同样的方法:P@anky_91为什么不使用explode~,因为它有更多的信息,它也会保留原来的索引:-)哈哈,我又贴了同样的:P@anky_91为什么不使用explode~,因为它有更多的信息,它也将保留原始索引:-)
   name  age category
0   Joe   32        A
0  Jane   35        A
1  Beth   33        B
1   Bob   32        B
2  John   35        C
3  Jill   33        D