![](/img/trans.png)
[英]using Python reduce Count the number of occurrence of character in string
[英]Python - Pandas - Count the number of character occurrence in a string and replace the string value
编辑:
我有以下数据帧
Name Code
Cedric AMMMM
Joe A
Mickael AMMCX
Dupond MMMMMMM
Jean AMMMCMC
我想计算代码列的值的字符出现次数。 并通过字符和出现次数的串联替换值。
我的预期结果如下:
Name Code
Cedric 1A4M
Joe 1A
Mickael 1A2M1C1X
Dupond 7M
Jean 1A3M1C1M1C
我尝试过以下方法:
for index, row in df.iterrows():
for i in "".join(set(row.Code)):
num = test.count(i)
df.loc[index,"Code"] = val + str(num) + i
但实际上我有一个超过80万行的巨大数据帧。 当我执行此代码时,过程太长。
我正在寻找一个更好的解决方案来做到这一点。
编辑:我在我的数据帧中添加了最后一个示例。 以前的响应不处理此示例。 我想处理这个用例
谢谢你的帮助。
使用列表理解和f-string
为python 3.6+
工作,并且还sorted
索引添加sorted
,以便不更改排序:
df['Code'] = [''.join(f'{x.count(i)}{i}' for i in sorted(set(x),key=x.index)) for x in df['Code']]
或使用Counter
:
from collections import Counter
df['Code'] = [''.join(f'{j}{i}' for i, j in Counter(x).items()) for x in df['Code']]
print (df)
Name Code
0 Cedric 1A4M
1 Joe 1A
2 Mickael 1A2M1C1X
3 Dupond 7M
表现 :
#[40000 rows x 2 columns]
df = pd.concat([df] * 10000, ignore_index=True)
In [119]: %timeit df['Code'] = [''.join(f'{j}{i}' for i, j in Counter(x).items()) for x in df['Code']]
276 ms ± 9.97 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [120]: %timeit df['Code'] = [''.join(f'{x.count(i)}{i}' for i in sorted(set(x),key=x.index)) for x in df['Code']]
262 ms ± 3.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#U9-Forward solution
In [124]: %timeit df['Code']=df['Code'].apply(lambda x: ''.join([''.join(map(str,i)) for i in Counter(x).items()]))
339 ms ± 51 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
也许collections.Counter
在apply
参数中,并且还使用双重''.join
来创建一个dict
ionary的字符串:
from collections import Counter
df['Code']=df['Code'].apply(lambda x: ''.join([''.join(map(str,i)) for i in Counter(x).items()]))
现在:
print(df)
方法是:
Name Code
0 Cedric A1M4
1 Joe A1
2 Mickael A1M2C1X1
3 Dupond M7
计数必须关心非连续重复。
首先是一个编码代码的函数:
def encode(code):
cpt=1
n=len(code)
res=''
for i in range(n):
if i == n-1 or code[i] != code[i+1]:
res += str(cpt)+code[i]
cpt=1
else: cpt+=1
return res
示例: scan('AABBCA')
- > '2A2B1C1A'
。
然后只需应用: df['Code']=df.Code.apply(encode)
,用于:
Name Code
0 Cedric 1A4M
1 Joe 1A
2 Mickael 1A2M1C1X
3 Dupond 7M
4 Jean 1A3M1C1M1C
您可以使用Counter from collections
中的Counter from collections
来计算出现次数。 之后您可以join
键值和值对。 除此之外,您可以应用df.apply
函数
from collections import Counter as ctr
df['Code'] = df['Code'].apply(lambda x: ''.join([''.join(map(str, val[::-1])) for val in ctr(x).items()]))
在这里我使用val[::-1]
,因此输出将与您的预期相提并论。
Name Code
0 Cedric 1A4M
1 Joe 1A
2 Mickael 1A1X1C2M
3 Dupond 7M
谢谢大家,
以下是两种方法的比较:
from itertools import groupby
%timeit df['Code'] = [''.join(f"{len(''.join(group))}{key}" for key, group in groupby(x)) for x in df['Code']]
CPU times: user 511 µs, sys: 7 µs, total: 518 µs
Wall time: 524 µs
和
def encode(code):
cpt=1
n=len(code)
res=''
for i in range(n):
if i == n-1 or code[i] != code[i+1]:
res += str(cpt)+code[i]
cpt=1
else: cpt+=1
return res
%timeit result['CDSCENARIO']=result.CDSCENARIO.apply(encode)
CPU times: user 855 µs, sys: 10 µs, total: 865 µs
Wall time: 871 µs
第一种方法比第二种方法快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.