我是 Python 初學者。我受到了一些 Python 課程的啟發。這是下面的示例 CSV 檔案。
| 姓名 | 地點 | 數字 |
|---|---|---|
| 安德魯·普拉特安德魯 | 美國廣播公司 | 100 |
| 史蒂文·雷霆 安德魯 | 美國廣播公司 | 50 |
| 杰夫英格蘭史蒂文 | 美國廣播公司 | 30 |
| 安德魯·英格蘭杰夫 | 美國廣播公司 | 30 |
我想得到這樣的結果:
['Andrew': 180,
'Platt': 100,
'Steven': 80,
'Jeff': 60,
'England': 60,
'Thunder':50,
'Andrew Platt': 100,
'Platt Andrew': 100,
'Steven Thunder': 50,
'Thunder Andrew': 50,
'Jeff England': 30,
'England Steven': 30,
'Andrew England': 30,
'England Jeff': 30]
邏輯:
one_words例如'Andrew',因為它顯示第1、2和4行,所以結果是180 (100 50 30)
two_words,例如'Andrew Platt',因為它只顯示第1行,所以結果是100
這是我在下面嘗試過的:
from collections import Counter
from itertools import combinations
import itertools
from pprint import pprint
import pandas as pd
data=[
"Andrew Platt Andrew;100,",
"Steven Thunder Andrew;50",
"Jeff England Steven;30",
"Andrew England Jeff;30"
]
one_words=Counter()
two_words=Counter()
df=[n.split(";") for n in data[0:]]
df=pd.DataFrame(df[1:],columns=df[0])
df.columns=('Name','Number')
df=df.replace('\,','',regex=True)
df['Number']=df.Number.replace('W','',regex=True)
items=" ".join(df.Name).split()
for item in set(items):
one_words[item] = df.loc[df.Name.str.contains(item)].Number.astype('int').sum()
for two_word in combinations(items, 2):
if len(set(two_word)) == 1:
continue
two_words[" ".join(two_word)] = df.loc[df.Name.str.contains(item)].Number.astype('int').sum()
pprint(one_words)
pprint(two_words)
我的結果:
Counter({'Andrew': 180,
'Platt': 100,
'Steven': 80,
'Jeff': 60,
'England': 60,
'Thunder': 50})
Counter({'Andrew Platt': 100,
'Platt Andrew': 100,
'Steven Thunder': 50,
'Steven Andrew': 50,
'Thunder Andrew': 50,
'Jeff England': 30,
'Jeff Steven': 30,
'England Steven': 30,
'Andrew England': 30,
'Andrew Jeff': 30,
'England Jeff': 30})
問題:
對于two_words, like [a,b,c], 輸出應該是[[a,b],[b,c]], 那意味著不應該有 likeSteven Andrew': 50,
注:
Python 版本為 3.8.13
uj5u.com熱心網友回復:
這是可以做到的。
from itertools import chain, pairwise
df['Key'] = df['Name'].apply(lambda x: list(set(chain.from_iterable((x.split(' '), map(' '.join, pairwise(x.split(' '))))))))
df.explode('Key').groupby('Key').Number.agg('sum').to_dict()
輸出
{'Andrew': 180,
'Andrew England': 30,
'Andrew Platt': 100,
'England': 60,
'England Jeff': 30,
'England Steven': 30,
'Jeff': 60,
'Jeff England': 30,
'Platt': 100,
'Platt Andrew': 100,
'Steven': 80,
'Steven Thunder': 50,
'Thunder': 50,
'Thunder Andrew': 50}
uj5u.com熱心網友回復:
您的代碼看起來不錯,只需替換itertools.combinations為itertools.pairwise(python ≥3.10,或使用zip(items, items[1:]))。
為一個熊貓解決方案:
out = (df.assign(L=[list(dict.fromkeys((l:=x.split()))) list(map(' '.join, zip(l, l[1:]))) for x in df['Name']])
.explode('L').groupby('L', sort=False)['Number']
.sum().sort_index(key=lambda x: x.str.count(' ')).to_dict()
)
對于像您的原始代碼這樣的兩步解決方案:
df2 = df.assign(L=[list(zip((l:=x.split()), l[1:])) for x in df['Name']]).explode('L')
pd.concat([df2.explode('L').drop_duplicates(['Name', 'L']).groupby('L', sort=False)['Number'].sum(),
df2.assign(L=df2['L'].agg(' '.join)).groupby('L', sort=False)['Number'].sum()]).to_dict()
輸出:
{'Andrew': 180,
'Platt': 100,
'Steven': 80,
'Thunder': 50,
'Jeff': 60,
'England': 60,
'Andrew Platt': 100,
'Platt Andrew': 100,
'Steven Thunder': 50,
'Thunder Andrew': 50,
'Jeff England': 30,
'England Steven': 30,
'Andrew England': 30,
'England Jeff': 30}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/519747.html
標籤:Python熊猫数据框
上一篇:獲取資料框列的絕對值之和
