Python 使用另一列的值列表在dataframe中创建新列,而不使用;groupby“;
我处理大型数据集,使pandas group和groupby函数花费很长时间/占用太多内存。我听一些人说groupby可能很慢,但我很难找到更好的解决方案 如果我的dataframe有两列类似于:Python 使用另一列的值列表在dataframe中创建新列,而不使用;groupby“;,python,pandas,Python,Pandas,我处理大型数据集,使pandas group和groupby函数花费很长时间/占用太多内存。我听一些人说groupby可能很慢,但我很难找到更好的解决方案 如果我的dataframe有两列类似于: df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]}) a b 1 1 2 1 2 1 4 1 我希望返回与另一列中的值匹配的值列表: a b l
df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
a b
1 1
2 1
2 1
4 1
我希望返回与另一列中的值匹配的值列表:
a b list_of_b
1 1 [1]
2 1 [1,1]
2 1 [1,1]
4 1 [1]
我目前使用:
df_group = df.groupby('a')
df['list_of_b'] = df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1)
上面的代码适用于小数据帧,但不适用于大数据帧(df>1000000行)。有人有更快的方法吗?在4K行df上,我得到以下信息:
In [29]:
df_group = df.groupby('a')
%timeit df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1)
%timeit df['a'].map(df.groupby('a')['b'].apply(list))
1 loops, best of 3: 4.37 s per loop
100 loops, best of 3: 4.21 ms per loop
在4K行df上,我得到以下信息:
In [29]:
df_group = df.groupby('a')
%timeit df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1)
%timeit df['a'].map(df.groupby('a')['b'].apply(list))
1 loops, best of 3: 4.37 s per loop
100 loops, best of 3: 4.21 ms per loop
仅进行分组,然后连接回原始数据帧似乎要快得多:
def make_lists(df):
g = df.groupby('a')
def list_of_b(x):
return x.b.tolist()
return df.set_index('a').join(
pd.DataFrame(g.apply(list_of_b),
columns=['list_of_b']),
rsuffix='_').reset_index()
这将为每个循环提供192ms,并生成1M行,如下所示:
df1 = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
low = 1
high = 10
size = 1000000
df2 = pd.DataFrame({'a':np.random.randint(low,high,size),
'b':np.random.randint(low,high,size)})
make_lists(df1)
Out[155]:
a b list_of_b
0 1 1 [1]
1 2 1 [1, 1]
2 2 1 [1, 1]
3 4 1 [1]
In [156]:
%%timeit
make_lists(df2)
10 loops, best of 3: 192 ms per loop
仅进行分组,然后连接回原始数据帧似乎要快得多:
def make_lists(df):
g = df.groupby('a')
def list_of_b(x):
return x.b.tolist()
return df.set_index('a').join(
pd.DataFrame(g.apply(list_of_b),
columns=['list_of_b']),
rsuffix='_').reset_index()
这将为每个循环提供192ms,并生成1M行,如下所示:
df1 = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
low = 1
high = 10
size = 1000000
df2 = pd.DataFrame({'a':np.random.randint(low,high,size),
'b':np.random.randint(low,high,size)})
make_lists(df1)
Out[155]:
a b list_of_b
0 1 1 [1]
1 2 1 [1, 1]
2 2 1 [1, 1]
3 4 1 [1]
In [156]:
%%timeit
make_lists(df2)
10 loops, best of 3: 192 ms per loop
我能想到的最短解决方案:
df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
df.join(pd.Series(df.groupby(by='a').apply(lambda x: list(x.b)), name="list_of_b"), on='a')
a b list_of_b
0 1 1 [1]
1 2 1 [1, 1]
2 2 1 [1, 1]
3 4 1 [1]
我能想到的最短解决方案:
df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
df.join(pd.Series(df.groupby(by='a').apply(lambda x: list(x.b)), name="list_of_b"), on='a')
a b list_of_b
0 1 1 [1]
1 2 1 [1, 1]
2 2 1 [1, 1]
3 4 1 [1]
创建一个值列表是有问题的,因为pandas希望将其转换为一个系列并在索引上对齐,您能否尝试
df['list_of_b']=df['a'].map(df.groupby('a')['b'].apply(list))
for speed创建一个值列表是有问题的,因为pandas希望将其转换为一个系列并在索引上对齐,你能试试速度方面的df['list\u of_b']=df['a'].map(df.groupby('a')['b'].apply(list))