Python 带有.agg()的数据帧多操作的进度条
我想对一个巨大的数据集应用.agg操作 例如,我有以下代码:Python 带有.agg()的数据帧多操作的进度条,python,pandas,tqdm,Python,Pandas,Tqdm,我想对一个巨大的数据集应用.agg操作 例如,我有以下代码: from tqdm import tqdm import pandas as pd df = pd.DataFrame({"A":[1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0], "B":[1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0], "C":[1.0, 1.5, 2
from tqdm import tqdm
import pandas as pd
df = pd.DataFrame({"A":[1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0],
"B":[1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0],
"C":[1.0, 1.5, 2.0, 2.0, 3.0, 4.0, 5.0, 6.0, 10.0],
"D":[2.0, 5.0, 3.0, 6.0, 4.0, 2.0, 5.0, 1.0, 2.0],
"E":['a', 'a', 'b', 'a', 'b', 'b', 'b', 'a', 'a']})
df2 = df.groupby('B').agg({
'C': 'mean',
'D': 'sum',
'E': lambda x: x.mode()
})
print(df2)
问题是我的原始数据集有2.000.000行。将其转换为130.000需要几分钟,我希望看到一个进度条
我尝试过
tqdm
,但我不知道如何在这里应用它。是否有任何类似于.progress\u apply()
的函数,但对于.agg()
?这将在运行时打印进度,其中进度由计算统计数据的组的分数来衡量。但我不确定这个循环会让你的计算慢多少
agger = {
'C': 'mean',
'D': 'sum',
'E': lambda x: x.mode()}
gcols = ['B'] # columns defining the groups
groupby = df.groupby(gcols)
ngroups = len(groupby)
gfrac = 0.3 # fraction of groups for which you want to print progress
gfrac_size = max((1, int(ngroups*gfrac)))
groups = []
rows = []
for i,g in enumerate(groupby):
if (i+1)%gfrac_size == 0:
print('{:.0f}% complete'.format(100*(i/ngroups)))
gstats = g[1].agg(agger)
if i==0:
if gstats.ndim==2:
newcols = gstats.columns.tolist()
else:
newcols = gstats.index.tolist()
groups.append(g[0])
rows.append(gstats.values.flat)
df3 = pd.DataFrame(np.vstack(rows), columns=newcols)
if len(gcols) == 1:
df3.index = groups
else:
df3.index = pd.MultiIndex.from_tuples(groups, names=gcols)
df3 = df3.astype(df[newcols].dtypes)
df3
C D E
1.0 1.5 10.0 a
2.0 3.0 12.0 b
3.0 7.0 8.0 a
另一种方法(尽管有点老套)是利用您使用自己的函数lambda x:x.mode
这一事实。由于使用此函数已经降低了速度,因此可以编写一个类来存储有关进度的信息。比如说,
import pandas as pd
import numpy as np
df = pd.DataFrame({"A":[1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0],
"B":[1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0],
"C":[1.0, 1.5, 2.0, 2.0, 3.0, 4.0, 5.0, 6.0, 10.0],
"D":[2.0, 5.0, 3.0, 6.0, 4.0, 2.0, 5.0, 1.0, 2.0],
"E":['a', 'a', 'b', 'a', 'b', 'b', 'b', 'a', 'a']})
df2 = df.groupby('B').agg({
'C': 'mean',
'D': 'sum',
'E': lambda x: x.mode()
})
print(df2)
class ModeHack:
def __init__(self, size=5, N=10):
self.ix = 0
self.K = 1
self.size = size
self.N = N
def mode(self, x):
self.ix = self.ix + x.shape[0]
if self.K*self.size <= self.ix:
print('{:.0f}% complete'.format(100*self.ix/self.N))
self.K += 1
return x.mode()
def reset(self):
self.ix = 0
self.K = 1
mymode = ModeHack(size=int(.1*df.shape[0]), N=df.shape[0])
mymode.reset()
agger = {
'C': 'mean',
'D': 'sum',
'E': lambda x: mymode.mode(x)}
df3 = df.groupby('B').agg(agger)
将熊猫作为pd导入
将numpy作为np导入
df=pd.DataFrame({“A”:[1.0,2.0,3.0,1.0,2.0,3.0,1.0,2.0,3.0],
“B”:[1.0,1.0,1.0,2.0,2.0,2.0,3.0,3.0,3.0],
“C”:[1.0,1.5,2.0,2.0,3.0,4.0,5.0,6.0,10.0],
“D”:[2.0,5.0,3.0,6.0,4.0,2.0,5.0,1.0,2.0],
“E”:[‘a’、‘a’、‘b’、‘a’、‘b’、‘b’、‘a’、‘a’]]
df2=df.groupby('B').agg({
‘C’:‘平均’,
‘D’:‘sum’,
“E”:lambda x:x.mode()
})
打印(df2)
类别ModeHack:
def uuu init uuuu(self,size=5,N=10):
self.ix=0
self.K=1
self.size=大小
self.N=N
def模式(自我,x):
self.ix=self.ix+x.shape[0]
如果self.K*self.size我以前见过,但我对此无能为力。我不需要使用apply()应用简单的操作。相反,我需要用agg()应用几个操作,因为这个例子非常好,呵呵,但是如何在用两列而不是一列过滤的数据帧中应用相同的操作呢df.B.nunique
仅对一列有效……我刚刚修改了它,以便从groupby对象中获得组数。因此,如果您更改为df.groupby(['A','B']),那么在您的示例中会得到9。再次修改以允许groupby语句中有多个列。这是一个非常好的尝试,但它大大延长了计算时间。我想以一种有效的方式做这件事是不可能的。我使用tqdm
pack改进了您的代码。它有一个更友好的显示。非常感谢您抽出时间。