![](/img/trans.png)
[英]How to iterate over previous rows to compare values in a Pandas DataFrame
[英]How to iterate over previous rows in a dataframe
我有三列:id(非唯一 id)、X(類別)和 Y(類別)。 (我還沒有要共享的數據集。我將嘗試使用較小的數據集復制我擁有的內容並盡快進行編輯)
我在一個非常小的子集上運行了一個 for 循環,根據這些結果,運行這段代碼可能需要 4 個多小時。 我正在尋找一種使用 pandas 來完成此任務的更快方法(可能使用 iterrows,比如在應用中迭代之前的行)
對於我檢查的每一行
if sum(check_X & check_Y & check_id)>0: then append 1 to the array else: append 0
您可能正在尋找duplicated
的:
df = pd.DataFrame({'id': [0, 0, 0, 1, 0],
'X': [1, 1, 2, 1, 1],
'Y': [2, 2, 2, 2, 2]})
df['dup'] = ~df[df.duplicated(['X', 'Y'])].duplicated('id', keep=False).loc[lambda x: ~x]
df['dup'] = df['dup'].fillna(False).astype(int)
print(df)
# Output
id X Y dup
0 0 1 2 0
1 0 1 2 0
2 0 2 2 0
3 1 1 2 1
4 0 1 2 0
使用duplicates()
編輯來自@Corralien 的答案可能會更快,並且是此特定問題的最佳答案。 但是,如果您有不同的事情要檢查,則 apply 會更加靈活。
您可以使用iterrows()
或apply()
來完成。 據我所知apply()
更快:
check_id, check_x, check_y = set(), set(), set()
def apply_func(row):
global check_id, check_x, check_y
if row["id"] not in check_id and row['x'] in check_x and row['y'] in check_y:
row['duplicate'] = 1
else:
row['duplicate'] = 0
check_id.add(row['id'])
check_x.add(row['x'])
check_y.add(row['y'])
return row
df.apply(apply_func, axis=1)
使用 iterrows():
check_id, check_x, check_y = set(), set(), set()
for i, row in df.iterrows():
if row["id"] not in check_id and row['x'] in check_x and row['y'] in check_y:
df.loc[i, 'duplicate'] = 1
else:
df.loc[i, 'duplicate'] = 0
check_id.add(row['id'])
check_x.add(row['x'])
check_y.add(row['y'])
這本質上就像@Corralien 的回答。 你想要的可以使用duplicated
來實現,因為它返回一個 Series 指示每個值是否出現在前面的值中,這正是“當前 X 是否與之前的任何 X 匹配”。 那么“id”的條件就是它的否定。 因為如果所有的計算結果都為 True,則需要 1,否則每行中的值為 0,因此您可以使用&
運算符並將生成的 boolean 系列轉換為 dtype int:
check_X = df['X'].duplicated()
check_Y = df['Y'].duplicated()
check_id = ~df['id'].duplicated()
out = (check_X & check_Y & check_id).astype(int)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.