我有一個 csv 檔案,其中有一個名為“作者”的列。在該列中,每一行都有幾個作者,用逗號分隔。在函式下方的代碼中,getAuthorNames 獲取該列中的所有作者姓名,并回傳一個包含所有作者姓名的陣列。
然后函式 authCount 計算個人姓名在 Author 列中出現的次數。起初,我用幾百行來做,沒有任何問題。現在我正在嘗試使用 20,000 行以上來完成它,它已經花費了幾個小時,但仍然沒有結果。我相信是嵌套的 for 回圈和 if 陳述句導致它花費了這么長時間。任何關于如何加快行程的建議都會有所幫助。我應該使用 lambda 嗎?是否有內置的熊貓功能可以提供幫助?
這是輸入資料的樣子:
Title,Authors,ID
XXX,"Wang J, Wang H",XXX
XXX,"Wang J,Han H",XXX
這就是輸出的樣子
Author,Count
Wang J,2
Wang H,1
Han H,1
這是代碼:
import pandas as pd
df = pd.read_csv (r'C:\Users\amos.epelman\Desktop\Pubmedpull3GC.csv')
def getAuthorNames(dataFrame):
arrayOfAuthors = []
numRows = dataFrame.shape[0]
cleanDF = dataFrame.fillna("0")
for i in range (0,numRows):
miniArray = cleanDF.at[i,"Authors"].split(",")
arrayOfAuthors = miniArray
return arrayOfAuthors
def authCount(dataFrame):
authArray = getAuthorNames(dataFrame)
numAuthors = len(authArray)
countOfAuth = [0] * numAuthors
newDF = pd.DataFrame({"Author Name": authArray, "Count": countOfAuth})
refDF = dataFrame.fillna("0")
numRows= refDF.shape[0]
for i in range (0,numAuthors):
for j in range (0,numRows):
if newDF.at[i, "Author Name"] in refDF.at[j,"Authors"]:
newDF.at[i,"Count"] = 1
sortedDF = newDF.sort_values(["Count"], ascending = False)
noDupsDF = sortedDF.drop_duplicates(subset ="Author Name", keep = False)
return noDupsDF
finalDF = authCount(df)
file_name = 'GC Pubmed Pull3 Author Names with Count.xlsx'
finalDF.to_excel(file_name)
uj5u.com熱心網友回復:
您可以嘗試使用 Counter 和 lambda 函式來消除兩個資料幀上的嵌套 for 回圈,這似乎是添加新列的緩慢方法
from collections import Counter
然后得到“計數”列
author_counts = Counter(list(refDF["Authors"]))
newDF["Count"] = newDF.apply(lambda r: author_counts[r["Author Name"]], axis=1)
uj5u.com熱心網友回復:
您可以使用Python 標準庫中的csv 閱讀器和集合 Counter類來執行此操作。
我制作了一個示例 CSV,其中包含 20K 行隨機生成的名稱,如您所描述的random_names.csv:
Authors
"Darnel D, Blythe B"
"Wang H, Darnel D, Alice A"
"Wang J, Wang H, Darnel D, Blythe B"
"Han H, Wang J"
"Clarice C, Wang H, Darnel D, Alice A"
"Clarice C, Han H, Blythe B, Wang J"
"Clarice C, Darnel D, Blythe B"
"Clarice C, Wang H, Blythe B"
"Blythe B, Wang J, Darnel D"
...
我的代碼沒有排序,但指出了在哪里插入排序。這在一秒鐘內運行(在我的 M1 Macbook Air 上):
import csv
from collections import Counter
author_counts = Counter()
with open('random_names.csv', newline='') as f:
reader = csv.reader(f)
next(reader) # discard header
for row in reader:
authors = row[0] # !! adjust for your data
for author in authors.split(','):
author_counts.update([author.strip()])
# Sort here
print(author_counts.items())
with open('output.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Author','Count'])
writer.writerows(author_counts.items())
它列印出這個除錯行:
dict_items([('Darnel D', 10690), ('Blythe B', 10645), ('Wang H', 10881), ('Alice A', 10750), ('Wang J', 10613), ('Han H', 10814), ('Clarice C', 10724)])
并將其保存為output.csv:
Author,Count
Darnel D,10690
Blythe B,10645
Wang H,10881
Alice A,10750
Wang J,10613
Han H,10814
Clarice C,10724
uj5u.com熱心網友回復:
# take series of authors and split at comma and expand into dataframe
authors = df['author'].str.split(pat=',', expand=True)
authors.melt().value_counts()
我不確定它是否更快,但這應該會給你獨特的價值和數量。
輸入:
x y z author book
0 0 0 aa,bb,cc l
0 0 0 a,b,c l
0 0 0 aa,bb,c l
0 0 0 aa,b,c l
輸出:
variable value
0 aa 3
2 c 3
1 b 2
bb 2
0 a 1
2 cc 1
dtype: int64
更新:
此解決方案對輸出進行排序而不保存到檔案并%%timeit%給出:
7.03 ms ± 396 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
@ZachYoung 解決方案不排序并且不保存輸出%%timeit給出:
5.64 ms ± 208 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我在一個有 8000 個名字的測驗檔案上運行了這個
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/413682.html
標籤:
上一篇:聚合特定檔案夾的未知csv檔案
下一篇:繪制帶有可讀時間戳的csv檔案?
