我有一个字符串元组。我想按字符串的长度分组。这可以通过
完成import pandas as pd
data = 'aaa', 'bb', 'ccc', 'dd', 'eeee', 'ff'
df = pd.DataFrame(data, columns=['string'])
def length(index):
return len(df.at[index, 'string'])
for length, group in df.groupby(by=length):
print(group)
print('(length:', str(length) + ')', end='\n\n')
string
1 bb
3 dd
5 ff
(length: 2)
string
0 aaa
2 ccc
(length: 3)
string
4 eeee
(length: 4)
现在我的问题:
我真的需要创建一个函数len(df.at[index, column]
以便按长度对单列数据帧进行分组吗?
这是分组自定义功能的最佳方法吗?该解决方案(适用于具有140,000个单词的文件)与带有字典的纯Python解决方案之间的比较表明,该解决方案的运行时间为32.5(!)秒,而Python解决方案的运行时间为0.95秒。
答案 0 :(得分:0)
pandas DataFrame和Series已经具有.hist()
方法。
您可以简单地做到
import pandas as pd
data = 'aaa', 'bb', 'ccc', 'dd', 'eeee', 'ff'
df = pd.DataFrame(data, columns=['password'])
df['password'].str.len().hist()
或者,如果不进行df处理,也可以(作为解决方案1),
pd.Series(data).str.len().hist()
结帐documentation,了解如何自定义情节
答案 1 :(得分:0)
我们有series groupby
for x, y in df.groupby(df.string.str.len()):
print(y)
print('(length:', str(x) + ')', end='\n\n')
string
1 bb
3 dd
5 ff
(length: 2)
string
0 aaa
2 ccc
(length: 3)
string
4 eeee
(length: 4)
答案 2 :(得分:0)
免责声明:这实际上是评论,但可以作为正确格式的答案。
Ben的回答在某种程度上回答了您的问题1:不,您不需要创建函数来进行分组。更不用说您的自定义函数可能会很慢,因为它每次都会调用at
访问。通过性能比较可以看出:
# random data
np.random.seed(1)
data= [''.join(np.random.choice(list('abcdefgh'),np.random.randint(5,10)) )
for _ in range(100000)]
df = pd.DataFrame(data, columns = ['string'])
def length(index):
return len(df.at[index, 'string'])
# Your solution:
%%time
x=0
for length, group in df.groupby(length):
x+=length
# CPU times: user 451 ms, sys: 0 ns, total: 451 ms
# Wall time: 450 ms
# Ben's solution
%%time
x=0
for x, y in df.groupby(df.string.str.len()):
x+=length
# CPU times: user 35.5 ms, sys: 0 ns, total: 35.5 ms
# Wall time: 34.2 ms
注意,这两个函数在for
循环内使用简单的功能。在您的代码中,print
将成为瓶颈,因为打印到终端总是很慢。我高度怀疑纯Python分组功能是否可以和Ben的解决方案一样快。请发布该解决方案,我很高兴得知自己对此做错了。
答案 3 :(得分:0)
以Ben和Quang Hoang的答案为基础:我需要一个通用的按功能分组行解决方案(该数学术语为“等价类”)。要考虑的一件事是,并非所有函数都具有len
和pandas.Series.str.len
之类的“向量化”等效项。
解决方案:
def groupby(df, projection=lambda x: x, label=0):
'''
group dataframe into equivalence classes
see http://en.wikipedia.org/wiki/Equivalence_relation
'''
return df.groupby(by=df.loc[:, label].apply(projection), sort=False)
现在在上述文件中使用groupby(df, len)
并使用140,000个单词需要0.45秒而不是32.5秒。这意味着pandas group-by解决方案的速度是使用字典的纯Python解决方案的两倍。感谢Ben和Quang Hoang的投入。