我需要该程序完成从已存储在一个系列中的列表数据中获取单个字符的数量。下面是我希望程序完成的一个示例:
char_list = ['LNTS', 'AGTS', 'LMFS', 'PGST']
#end result (higher to lower frequency)
S : 4
T : 3
L : 2
G : 2
N : 1
A : 1
M : 1
F : 1
P : 1
我知道这可以用普通的Python完成,但我正试图找到Pandas的等效版本。到目前为止,我已经得到:
pd.Series(char_list).value_counts())
但是这会返回整个序列相对于单个字符的数量。如果有任何帮助就太好了。
pandas
并不特别适合处理这类问题。它可以完成,但最终你要么只是要迭代系列,而不是列表(真的没有什么不同),或者如果你真的想用不同的pandas
方式来做,它将涉及一些缓慢的.str
。方法。
你得到你想要的最简单的方法是collections
+itertools
。使用Counter
并将所有单独的单词链接在一起。然后,您可以从字典中生成Series
并对其进行排序。
from collections import Counter
from itertools import chain
import pandas as pd
pd.Series(Counter(chain.from_iterable(char_list))).sort_values(ascending=False)
S 4
T 3
L 2
G 2
N 1
A 1
M 1
F 1
P 1
dtype: int64
如果您想使用pandas
,您可以将单词split
放入每个字母中,在开头和结尾放置空字符串,然后使用explode
和value_counts
。但这比上面的要复杂得多,而且可能要慢得多。
s = (pd.Series(char_list)
.str.split('')
.str[1:-1]
.explode()
.value_counts())
S 4
T 3
L 2
G 2
N 1
A 1
M 1
F 1
P 1
dtype: int64
解决这个问题的核心问题是每个单元格都包含一个字符串值,因此任何pandas
操作都会将整个单元格视为单个单元。为了解决这个问题,有必要对数据进行转换,使每个单元格都是一个单字符字符串。
有许多不同效率的方法,但它们基本上都依赖于将字符串列转换为单字符字符串列。
- 创建
chain.from_interable
然后应用Series.value_counts
:
from itertools import chain
import pandas as pd
char_list = ['LNTS', 'AGTS', 'LMFS', 'PGST']
output = pd.Series(chain.from_iterable(char_list)).value_counts()
map
每串成一个列表,然后Series.explode
和value_counts
:
import pandas as pd
char_list = ['LNTS', 'AGTS', 'LMFS', 'PGST']
output = pd.Series(map(list, char_list)).explode().value_counts()
Series.apply
或Series.map
列出explode
和value_counts
:
import pandas as pd
char_list = ['LNTS', 'AGTS', 'LMFS', 'PGST']
output = pd.Series(char_list).apply(list).explode().value_counts()
import pandas as pd
char_list = ['LNTS', 'AGTS', 'LMFS', 'PGST']
output = pd.Series(char_list).map(list).explode().value_counts()
所有选项产生:output
:
S 4
T 3
L 2
G 2
N 1
A 1
M 1
F 1
P 1
dtype: int64
一些计时信息通过%timeit:
%timeit pd.Series(chain.from_iterable(char_list)).value_counts()
273 µs ± 10.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit pd.Series(map(list, char_list)).explode().value_counts()
358 µs ± 12.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit pd.Series(char_list).map(list).explode().value_counts()
428 µs ± 19.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit pd.Series(char_list).apply(list).explode().value_counts()
508 µs ± 36.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
来自@ALollz的回答:
%timeit pd.Series(Counter(chain.from_iterable(char_list))).sort_values(ascending=False)
215 µs ± 7.61 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit pd.Series(char_list).str.split('').str[1:-1].explode().value_counts()
677 µs ± 14.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
import pandas as pd
char_list = ['LNTS', 'AGTS', 'LMFS', 'PGST']
pd.Series(x for x in ''.join(char_list)).value_counts()