将pandas DataFrame列展开为多行

本文探讨了如何将包含列表的Pandas DataFrame列展开为多行,并对比了四种不同的实现方法:使用itertuples、repeat、apply和append。通过性能测试,发现使用repeat方法在运行时间上显著优于其他方法,对于大数据集是最佳选择。
摘要由CSDN通过智能技术生成
"""
问题描述:
将pandas DataFrame列展开为多行
如果我有这样一个DataFrame:
pd.DataFrame( {"name" : "John",
               "days" : [[1, 3, 5, 7]]
              })
给出了这种结构:
           days  name
0  [1, 3, 5, 7]  John
如何将其扩展到以下内容?
   days  name
0     1  John
1     3  John
2     5  John
3     7  John

参考:
# https://www.cnpython.com/qa/69057
# https://stackoverflow.com/questions/38203352/expand-pandas-dataframe-column-into-multiple-rows/38203702#38203702
"""

import numpy as np
import pandas as pd
import time


# 测试函数运行时间
def cal_time(fn):
    """计算性能的修饰器"""

    def wrapper(*args, **kwargs):
        starTime = time.time()
        f = fn(*args, **kwargs)
        endTime = time.time()
        print('%s() runtime:%s ms' % (fn.__name__, 1000 * (endTime - starTime)))
        return f

    return wrapper


N = 10 ** 3
df = pd.DataFrame({"name": np.random.choice(list('ABCD'), size=N),
                   "days": [np.random.randint(10, size=np.random.randint(5))
                            for i in range(N)]})


@cal_time
def using_itertuples(df):
    return pd.DataFrame([(d, tup.name) for tup in df.itertuples() for d in tup.days])


@cal_time
def using_repeat(df):
    lens = [len(item) for item in df['days']]
    return pd.DataFrame({"name": np.repeat(df['name'].values, lens),
                         "days": np.concatenate(df['days'].values)})


@cal_time
def using_apply(df):
    return (df.apply(lambda x: pd.Series(x.days), axis=1)
            .stack()
            .reset_index(level=1, drop=1)
            .to_frame('day')
            .join(df['name']))


@cal_time
def using_append(df):
    df2 = pd.DataFrame(columns=df.columns)
    for i, r in df.iterrows():
        for e in r.days:
            new_r = r.copy()
            new_r.days = e
            df2 = df2.append(new_r)
    return df2


res1 = using_itertuples(df)
res2 = using_repeat(df)
res3 = using_apply(df)
res4 = using_append(df)
# print(res1)
# print(res2)
# print(res3)
# print(res4)
"""
using_itertuples() runtime:3.0002593994140625 ms
using_repeat() runtime:0.9989738464355469 ms
using_apply() runtime:211.03239059448242 ms
using_append() runtime:2896.979331970215 ms
明显using_repeat 是最好的选择.
"""

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值