我有一个如下所示的DataFrames:
DF1 =
sID token A B C D
10 I am a f g h
10 here a g g h
10 whats a h g h
10 going a o g h
10 on a j g h
10 . a f g h
11 I am a f g h
11 foo bar a f g h
12 You are a f g h
...
(A-D)列与该任务无关。有没有一种方法可以添加一个计数器列,该计数器列对DataFrame中的单词(由空格分隔)进行计数。该列应开始计算每个sID
的令牌数量。这意味着每次sID
的值更改时,它都会重置。
通常,我只使用DF.groupby("sID").cumcount()
,但这仅计算每个sID
的行数。
结果应如下所示:
DF2 =
sID token A B C D Counter
10 I am a f g h 0 1
10 here a g g h 2
10 whats a h g h 3
10 going a o g h 4
10 on a j g h 5
10 . a f g h 6
11 I am a f g h 0 1
11 foo bar a f g h 2 3
12 You are a f g h 0 1
...
答案 0 :(得分:3)
在使用groupby("sID").cumcount()
之前,您需要进行一些操作以使单词一直排到第一行,一旦拆分,它们就属于该单词。因此,您可以按以下方式创建“计数器”列:
df['Counter']= (df.set_index('sID',append=True)['token']
.str.split(' ',expand=True).stack()
.groupby('sID').cumcount()
.groupby(level=0).apply(lambda x: ' '.join([str(i) for i in x])))
您将获得预期的输出
答案 1 :(得分:3)
使用groupby
+ itertools
:
from itertools import chain, count
df = pd.DataFrame({'sID': [10, 10, 10, 10, 10, 10, 11, 11, 12],
'token': ['I am', 'here', 'whats', 'going',
'on', '.', 'I am', 'foo bar', 'You are']})
def counter(df):
for k, g in df.groupby('sID')['token']:
c = count()
lens = g.str.split().map(len)
yield [' '.join([str(next(c)) for _ in range(n)]) for n in lens]
df['Counts'] = list(chain.from_iterable(counter(df)))
结果
print(df)
sID token Counts
0 10 I am 0 1
1 10 here 2
2 10 whats 3
3 10 going 4
4 10 on 5
5 10 . 6
6 11 I am 0 1
7 11 foo bar 2 3
8 12 You are 0 1
说明
itertools.count
计数器。str.split
和len
对单词数进行计数。itertools.chain
跟踪结果。