Python pandas-使用元素的计数和频率创建数据帧
从以下数据帧开始Python pandas-使用元素的计数和频率创建数据帧,python,pandas,Python,Pandas,从以下数据帧开始df: df = pd.DataFrame({'node':[1,2,3,3,3,5,5],'lang':['it','en','ar','ar','es','uz','es']}) 我正在尝试构建结构: node langs lfreq 0 1 [it] [1] 1 2 [en] [1] 2 3 [ar, es] [2, 1] 3 5 [uz, es] [1, 1] 因此
df
:
df = pd.DataFrame({'node':[1,2,3,3,3,5,5],'lang':['it','en','ar','ar','es','uz','es']})
我正在尝试构建结构:
node langs lfreq
0 1 [it] [1]
1 2 [en] [1]
2 3 [ar, es] [2, 1]
3 5 [uz, es] [1, 1]
因此,基本上是通过列表将每个节点的lang
元素和频率分组到一行中。到目前为止我所做的:
# Getting the unique langs / node
a = df.groupby('node')['lang'].unique().reset_index(name='langs')
# Getting the frequency of lang / node
b = df.groupby('node')['lang'].value_counts().reset_index(name='lfreq')
c = b.groupby('node')['lfreq'].unique().reset_index(name='lfreq')
然后在节点上进行合并
:
d = pd.merge(a,c,on='node')
经过这次操作,我得到的是:
node langs lfreq
0 1 [it] [1]
1 2 [en] [1]
2 3 [ar, es] [2, 1]
3 5 [uz, es] [1]
您可能会注意到,最后一行只有一个
[1]
出现两个[uz,es]
的频率,而不是预期的[1,1]
列表。是否有一种方法可以以更简洁的方式执行分析,以获得所需的输出?我将使用agg函数和tolist()
替换
c = b.groupby('node')['lfreq'].unique().reset_index(name='lfreq')
与
和中提琴:
node langs lfreq
0 1 [it] [1]
1 2 [en] [1]
2 3 [ar, es] [2, 1]
3 5 [uz, es] [1, 1]
您可以使用参数返回\u counts=True
:
df = pd.DataFrame({'node':[1,2,3,3,3,5,5],'lang':['it','en','ar','ar','es','uz','es']})
print df
lang node
0 it 1
1 en 2
2 ar 3
3 ar 3
4 es 3
5 uz 5
6 es 5
a = df.groupby('node')['lang'].apply(lambda x: np.unique(x, return_counts=True))
.reset_index(name='tup')
#split tuples
a[['langs','lfreq']] = a['tup'].apply(pd.Series)
#filter columns
print a[['node','langs','lfreq']]
node langs lfreq
0 1 [it] [1]
1 2 [en] [1]
2 3 [ar, es] [2, 1]
3 5 [es, uz] [1, 1]
在某种程度上,因为您(在评论中)提到了速度对于拥有4000万行的重要性,所以我建议您查看以下内容
df.groupby(['node','lang'])['lang'].count()
node lang
1 it 1
2 en 1
3 ar 2
es 1
5 es 1
uz 1
一般来说,使用更平坦的结构(python的zen)会更好,更具体地说,您希望pandas/numpy列是简单类型(int和float),而不是对象
考虑到groupby等pandas方法,上述结构应该比以列表形式存储更容易操作,而且几乎可以保证速度更快,可能更快。我假设您希望使用此结构进行进一步处理,但即使不使用,也可以通过这种方式将数据制成表格。谢谢。与其他答案相比,速度如何?我知道,在一个50万行的数据帧上,应用大型数据帧(我有近4000万行)的速度很慢,@JohnE solution比dmb(64秒)和jezrael(136秒)快得多(1.5秒)。
df = pd.DataFrame({'node':[1,2,3,3,3,5,5],'lang':['it','en','ar','ar','es','uz','es']})
print df
lang node
0 it 1
1 en 2
2 ar 3
3 ar 3
4 es 3
5 uz 5
6 es 5
a = df.groupby('node')['lang'].apply(lambda x: np.unique(x, return_counts=True))
.reset_index(name='tup')
#split tuples
a[['langs','lfreq']] = a['tup'].apply(pd.Series)
#filter columns
print a[['node','langs','lfreq']]
node langs lfreq
0 1 [it] [1]
1 2 [en] [1]
2 3 [ar, es] [2, 1]
3 5 [es, uz] [1, 1]
df.groupby(['node','lang'])['lang'].count()
node lang
1 it 1
2 en 1
3 ar 2
es 1
5 es 1
uz 1