我有一个熊猫数据帧df像:
a b
A 1
A 2
B 5
B 5
B 4
C 6
我想按第一列分组,并将第二列作为行中的列表:
A [1,2]
B [5,5,4]
C [6]
是否有可能使用pandas groupby来做这样的事情?
我有一个熊猫数据帧df像:
a b
A 1
A 2
B 5
B 5
B 4
C 6
我想按第一列分组,并将第二列作为行中的列表:
A [1,2]
B [5,5,4]
C [6]
是否有可能使用pandas groupby来做这样的事情?
当前回答
排序耗时O(nlog(n)),是上述方案中耗时最多的操作
对于简单的解决方案(含单列)pd.Series。除非考虑其他框架,否则To_list可以工作并且可以被认为更有效
e.g.
import pandas as pd
from string import ascii_lowercase
import random
def generate_string(case=4):
return ''.join([random.choice(ascii_lowercase) for _ in range(case)])
df = pd.DataFrame({'num_val':[random.randint(0,100) for _ in range(20000000)],'string_val':[generate_string() for _ in range(20000000)]})
%timeit df.groupby('string_val').agg({'num_val':pd.Series.to_list})
对于2000万条记录,大约需要17.2秒。相比之下,apply(list)大约需要19.2秒,lambda函数大约需要20.6秒
其他回答
有点老了,但我是被指引到这里的。有办法把它按多个不同的列分组吗?
"column1", "column2", "column3"
"foo", "val1", 3
"foo", "val2", 0
"foo", "val2", 3
"bar", "other", 99
:
"column1", "column2", "column3"
"foo", "val1", [ 3 ]
"foo", "val2", [ 0, 3 ]
"bar", "other", [ 99 ]
我发现的实现同样的事情的最简单的方法(至少对于一列)与Anamika的答案类似,只是使用了聚合函数的tuple语法。
df.groupby('a').agg(b=('b','unique'), c=('c','unique'))
如果性能是重要的,下降到numpy级别:
import numpy as np
df = pd.DataFrame({'a': np.random.randint(0, 60, 600), 'b': [1, 2, 5, 5, 4, 6]*100})
def f(df):
keys, values = df.sort_values('a').values.T
ukeys, index = np.unique(keys, True)
arrays = np.split(values, index[1:])
df2 = pd.DataFrame({'a':ukeys, 'b':[list(a) for a in arrays]})
return df2
测试:
In [301]: %timeit f(df)
1000 loops, best of 3: 1.64 ms per loop
In [302]: %timeit df.groupby('a')['b'].apply(list)
100 loops, best of 3: 5.26 ms per loop
这里我用“|”作为分隔符对元素进行分组
import pandas as pd
df = pd.read_csv('input.csv')
df
Out[1]:
Area Keywords
0 A 1
1 A 2
2 B 5
3 B 5
4 B 4
5 C 6
df.dropna(inplace = True)
df['Area']=df['Area'].apply(lambda x:x.lower().strip())
print df.columns
df_op = df.groupby('Area').agg({"Keywords":lambda x : "|".join(x)})
df_op.to_csv('output.csv')
Out[2]:
df_op
Area Keywords
A [1| 2]
B [5| 5| 4]
C [6]
是时候使用agg而不是apply了。
When
df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6], 'c': [1,2,5,5,4,6]})
如果你想让多个列堆叠到列表中,结果是pd。DataFrame
df.groupby('a')[['b', 'c']].agg(list)
# or
df.groupby('a').agg(list)
如果你想在列表中单列,结果在ps.Series
df.groupby('a')['b'].agg(list)
#or
df.groupby('a')['b'].apply(list)
注意,结果为pd。当你只聚合单列时,DataFrame大约比ps.Series中的结果慢10倍,在多列情况下使用它。