[英]Pandas substract above row
基本上這是我面臨的挑戰
具有時間范圍和唯一 ID 的數據集,我需要做的是查找 ID 在日期范圍內是否重復。
123 transaction 1/1/2021
345 transaction 1/1/2021
123 transaction 1/2/2021
123 transaction 1/20/2021
我想為 ID 123 返回 1,因為重復交易在 7 天的范圍內。
我可以使用 Excel 來做到這一點,並且我添加了更多的日期范圍,具體取決於日期,例如周三最多 6 天、周四 5 天、周五 4 天。 但我不知道如何用 pandas 來完成這個......
我想使用 pandas 執行此操作的原因是因為每個數據集最多有 1M 行,並且使用 Excel 需要很長時間才能完成,除此之外,我需要按類別進行拆分,而且做所有這些手動工作很痛苦.
關於如何完成這項任務有什么建議或想法嗎?
您提供的有關您的情況的上下文和數據很少,但您可能可以執行以下操作:
>>> df
id type date
0 123 transaction 2021-01-01
1 345 transaction 2021-01-01
2 123 transaction 2021-01-02
3 123 transaction 2021-01-20
>>> dupes = df.groupby(pd.Grouper(key='date', freq='W'))['id'].apply(pd.Series.duplicated)
>>> dupes
0 False
1 False
2 True
3 False
Name: id, dtype: bool
在那里,第2
項(第三項)為True
,因為過去一周已經發生了123
次。
據我了解這個問題,我認為這就是你所需要的。
from datetime import datetime
import pandas as pd
df = pd.DataFrame({
"id": [123, 345, 123, 123],
"name": ["transaction", "transaction", "transaction", "transaction"],
"date": ["01/01/2021", "01/01/2021", "01/02/2021", "01/10/2021"]
})
def dates_in_range(dates):
num_days_frame = 6
processed_dates = sorted([datetime.strptime(date, "%m/%d/%Y") for date in dates])
difference_in_range = any(abs(processed_dates[i] - processed_dates[i-1]).days < num_days_frame for i in range(1, len(processed_dates)))
return difference_in_range and 1 or 0
group = df.groupby("id")
df_new = group.apply(lambda x: dates_in_range(x["date"]))
print(df_new)
"""
print(df_new)
id
123 1
345 0
"""
在這里,您首先按id
分組,以便在同一行中獲得該特定 id 的所有日期。
之后,對聚合日期應用逐行 function 操作,以便首先對它們進行排序,然后檢查連續項目之間的差異是否大於定義的范圍。 如果日期接近,排序確保連續差異實際上會導致正確或錯誤的結果。
最后,如果存在任何連續排序日期的差小於num_days_frame
(6) 的此類行,則返回 1,否則返回 0。
話雖如此,這可能不如對每一行進行排序那樣高效。 避免這種情況的一種方法是首先對整個df
進行排序並應用組操作以確保排序日期。
自由度:
df = pd.read_csv(StringIO(
"""id,trans_date
123,1/1/2021
345,1/1/2021
123,1/2/2021
123,1/20/2021
345,1/3/2021
"""
)) # added extra record for demo
df
id trans_date
0 123 1/1/2021
1 345 1/1/2021
2 123 1/2/2021
3 123 1/20/2021
4 345 1/3/2021
df['trans_date'] = pd.to_datetime(df['trans_date'])
由於您必須分別查看每個 id,您可以按 id 分組,然后獲取最大和最小日期,如果差值大於 7,則為 1。否則為 0。
result = df.groupby('id')['trans_date'].apply(
lambda x: True if (x.max()-x.min()).days > 7 else False)
result
id
123 True
345 False
Name: trans_date, dtype: bool
如果您只需要所需的 ID,那么
result.index[result].values
array([123])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.