Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 利用100万条记录分组使用熊猫的有效方法_Python_Python 3.x_Pandas_Dataframe_Pandas Groupby - Fatal编程技术网

Python 利用100万条记录分组使用熊猫的有效方法

Python 利用100万条记录分组使用熊猫的有效方法,python,python-3.x,pandas,dataframe,pandas-groupby,Python,Python 3.x,Pandas,Dataframe,Pandas Groupby,我有一个数据帧,可以使用下面的代码生成 df2 = pd.DataFrame({'subject_ID':[1,1,1,1,1,1,2,2,2,2],'colum' : ['L1CreaDate','L1Crea','L2CreaDate','L2Crea','L3CreaDate','L3Crea','L1CreaDate','L1Crea','L2CreaDate','L2Crea'], 'dates':['2016-10-30 00:00:00',2.3,

我有一个数据帧,可以使用下面的代码生成

df2 = pd.DataFrame({'subject_ID':[1,1,1,1,1,1,2,2,2,2],'colum' : ['L1CreaDate','L1Crea','L2CreaDate','L2Crea','L3CreaDate','L3Crea','L1CreaDate','L1Crea','L2CreaDate','L2Crea'], 
                'dates':['2016-10-30 00:00:00',2.3,'2016-10-30 00:00:00',2.5,np.nan,np.nan,'2016-10-30 00:00:00',12.3,'2016-10-30 00:00:00',12.3]})
我试图在上面的数据帧上执行以下操作。虽然代码工作得非常好,但问题是当我使用
groupby语句时。它在示例数据帧中速度很快,但在具有100多万条记录的实际数据中,它需要一段时间,而且运行时间很长

    df2['col2'] = df2['colum'].str.split("Date").str[0]
    df2['col3'] = df2['col2'].str.extract('(\d+)', expand=True).astype(int)
    df2 = df2.sort_values(by=['subject_ID','col3'])
    df2['count'] = df2.groupby(['subject_ID','col2'])['dates'].transform(pd.Series.count)
我使用
groupby
获得下面的输出
count
列,这样我就可以拒绝count为
0
的记录。放弃NA是有逻辑的。这不仅仅是放弃所有的NA。如果你想知道这一点,请参考这篇文章

在实际数据中,一个人可能有超过10000行。因此,单个数据帧有超过100万行

有没有其他更好更有效的方法来执行
groupby
或获取
count


思想是使用列表理解和
拆分
来提高性能,然后不将输出分配给新列
计数
,而是使用提取的整数进行过滤和最后排序:

df2['col2'] = [x.split("Date")[0] for x in df2['colum']]
df2 = df2[df2.groupby(['subject_ID','col2'])['dates'].transform('count').ne(0)].copy()

df2['col3'] = df2['col2'].str.extract('(\d+)', expand=True).astype(int)
df2 = df2.sort_values(by=['subject_ID','col3'])
print (df2)
   subject_ID       colum                dates    col2  col3
0           1  L1CreaDate  2016-10-30 00:00:00  L1Crea     1
1           1      L1Crea                  2.3  L1Crea     1
2           1  L2CreaDate  2016-10-30 00:00:00  L2Crea     2
3           1      L2Crea                  2.5  L2Crea     2
6           2  L1CreaDate  2016-10-30 00:00:00  L1Crea     1
7           2      L1Crea                 12.3  L1Crea     1
8           2  L2CreaDate  2016-10-30 00:00:00  L2Crea     2
9           2      L2Crea                 12.3  L2Crea     2
如果获取错误:

AttributeError:“float”对象没有属性“split”

这意味着可能缺少值,因此应更改列表理解:

df2['col2'] = [x.split("Date")[0] if x == x else np.nan for x in df2['colum']]
检查性能:

def new(df2):
    df2['col2'] = [x.split("Date")[0] for x in df2['colum']]
    df2 = df2[df2.groupby(['subject_ID','col2'])['dates'].transform('count').ne(0)].copy()
    df2['col3'] = df2['col2'].str.extract('(\d+)', expand=True).astype(int)
    return df2.sort_values(by=['subject_ID','col3'])


def orig(df2):
    df2['col2'] = df2['colum'].str.split("Date").str[0]
    df2['col3'] = df2['col2'].str.extract('(\d+)', expand=True).astype(int)
    df2 = df2.sort_values(by=['subject_ID','col3'])
    df2['count'] = df2.groupby(['subject_ID','col2'])['dates'].transform(pd.Series.count)
    return df2[df2['count'].ne(0)]

In [195]: %timeit (orig(df2))
10.8 ms ± 728 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [196]: %timeit (new(df2))
6.11 ms ± 144 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

我现在就试试。感谢您的回复。能在jupyter笔记本中找到每个单元格的执行时间吗?当我使用
%timeit
,它不会返回anything@AVLES-嗯,试试自定义函数,给我一些时间来解决问题。你的解决方案在性能上比我的好,你的Python知识很棒,令人钦佩。你们在论坛上的回答让我受益匪浅。谢谢你,我只是提个简单的问题。建议使用
.copy()
函数,而不仅仅是分配给新的数据帧。例如:
df3=df2.copy()
推荐/快于
df3=df2