我有一個要從中獲取資料的 excel 檔案。資料基本就是一天的表,大家一起玩
| 日 | pl1 | pl2 |
|---|---|---|
| 星期一 | 1000 | 1011 |
| 周二 | 1100 | 0101 |
| 周二 | 1000 | 0121 |
| 星期三 | 0101 | 1101 |
| 星期一 | 0210 | 1212 |
| 星期三 | 1000 | 0101 |
我想檢查一天內沒有 id 播放超過一次(無論它是在 pl1 還是 pl2 的列中)。例如,在星期三,我們有兩次“0101”,一次是 pl1,一次是 pl1,我想抓住這個。
我正在尋找哪種方式是最快和更 Pythonic 的方式。
我想過檢查 pl1 串列和 pl2 的所有元素,如果我在任何地方找到相同的值,請檢查當天列上的值是否相同。但是,我不僅認為這會非常緩慢地處理,而且我還認為檢查起來更復雜
另一個想法是將它們移動到串列 [[Mon,1000,1012],[Tue,1110,0101]...] 的串列中,然后按天對它們進行分組,然后還檢查其余元素?還是覺得時間太長了。
我應該創建一個touples串列嗎?(我已經使用元組并檢查沒有相同的對(相同的 id 和相同的位置 pl1 和 pl2)
有沒有更快更緊湊的方法?
謝謝
uj5u.com熱心網友回復:
我喜歡這個問題,這是一個不錯的小腦筋急轉彎!
Pandas 中可能有一些模塊工具可以使用 self join 或類似方法執行類似 sql 的操作,但我想看看是否可以僅使用核心 Python 輕松完成。
我想到的第一種方法是創建一個元組串列,其中每個元組是一對值,第一個是日期,第二個是玩家之一。每行值將生成 2 個元組,一個用于玩家 1,一個用于玩家 2。即第一行資料:
Mon,1000,1011
將被放入2個元組:
('Mon',1000),('Mon',1011)
將所有這些元組添加到串列中。然后在串列中搜索重復項,這是一項很常見的任務。假設玩家資料在一個名為“players.csv”的 csv 檔案中,如下所示:
day,pl1,pl2
Mon,1000,1011
Tue,1100,0101
Tue,1000,0121
Wed,0101,1101
Mon,0210,1212
Wed,1000,0101
下面的代碼應該回傳您正在尋找的資訊:
# import data
playerFile = open('players.csv','r')
playerData = playerFile.readlines()[1:]
playerFile.close()
# create list of tuples, 1 tuple for each player in line of data
plays = []
for line in playerData:
day,p1,p2 = line[:-1].split(',')
plays.extend([(day,p1),(day,p2)])
# now check the list for duplicate tuples
# since each tuple is a day that a player played,
# if a player played twice on 1 day, it'll be a duplicate
seen = set()
dupes = set()
for play in plays:
if play in seen:
dupes.add(play)
else:
seen.add(play)
# print duplicates
for dupe in dupes:
print(dupe)
輸出:
('Wed', '0101')
(請注意,對于每個“播放”,我必須使用元組而不是串列,因為我只想識別每個重復項一次,即如果玩家 0101一天玩了3次,我只想要一個專案。一套可以很好地做到這一點,但您不能將串列添加到集合中,因為它們是可變的)
uj5u.com熱心網友回復:
我認為這是pandas.DataFrame.groupby. 鑒于以下資料幀df:
day pl1 pl2
0 Mon '1000' '1011'
1 Tue '1100' '0101'
2 Tue '1000' '0121'
3 Wed '0101' '1101'
4 Mon '0210' '1212'
5 Wed '1000' '0101'
您可以set_index到'day',串聯玩家列,然后groupby在白天和球員,找到每個組的大小。這將產生玩家每天玩的次數。然后我們可以過濾出現多次的玩家。
import pandas as pd
out = df.set_index('day')
out = pd.concat([out['pl1'], out['pl2']]).reset_index().groupby(['day', 0]).size()
out = out[out>1]
輸出:
day 0
Wed '0101' 2
dtype: int64
另一種選擇是使用字典。我們可以首先創建字典temp來存盤每天的玩家 ID。然后我們可以使用collections.Counter計算每個玩家在某一天出現的次數并過濾出現超過一次的玩家。
from collections import Counter
temp = {}
for d in df.to_dict('records'):
temp.setdefault(d['day'], []).extend([d['pl1'],d['pl2']])
out = {}
for day, lst in temp.items():
out[day] = {pl: v for pl, v in Counter(lst).items() if v > 1}
輸出:
{'Mon': {}, 'Tue': {}, 'Wed': {'0101': 2}}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/386231.html
標籤:Python 熊猫 列表 数据框 pandas-groupby
