我正在尝试使用 Panda 来过滤 DataFrame,以找到长度不同的连续销售。我希望确定连续销售的时期,但也允许中间有几天没有销售。在下面的 df 中,我希望选择第 12 至 19 行。
data = [['2023-11-16', 1], ['2023-11-17', 0], ['2023-11-20', 1],
['2023-11-21', 0], ['2023-11-22', 1], ['2023-11-24', 0],
['2023-11-27', 0], ['2023-11-28', 0], ['2023-11-29', 0],
['2023-11-30', 0], ['2023-12-01', 0], ['2023-12-04', 0],
['2023-12-05', 1], ['2023-12-06', 1] , ['2023-12-07', 1],
['2023-12-08', 1], ['2023-12-11', 0], ['2023-12-12', 0],
['2023-12-13', 1], ['2023-12-14', 1], ['2023-12-15', 0],
['2023-12-18', 0], ['2023-12-19', 0], ['2023-12-20', 0]]
df = pd.DataFrame(data, columns=['date', 'sold'])
这是一个可定制的算法,应该对您的用例有所帮助:
def find_streaks(df: pd.DataFrame, allowed_no_sales = 2, minimum_streak = 4):
streaks: list[int, int] = []
start = 0
end = 0
current_sales = 0
current_no_sales = 0
for current in range(len(df)):
if df['sold'][current] == 0:
current_no_sales += 1
if current_no_sales > allowed_no_sales:
if current_sales >= minimum_streak:
streaks.append([start, end])
current_sales = 0
start = -1
else:
end = current
current_no_sales = 0
current_sales += 1
if start == -1:
start = current
if current_sales >= minimum_streak:
streaks.append([start, end])
return streaks
allowed_no_sales
是允许的连续无销售天数(这些无销售天可以按顺序出现多次,例如:1 0 0 0 [1 1 0 0 1 0 0 1 1 1 0 0 1] 0 0 0 1,捕获的序列位于括号之间 allowed_no_sales = 2
。
minimum_streak
是应出现在序列中的最小销售天数。例如,DataFrame 开头的 1 0 1 0 1 不会是 minimum_streak = 4
的条纹。
对于您的数据框:
import pandas as pd
data = [['2023-11-16', 1], ['2023-11-17', 0], ['2023-11-20', 1],
['2023-11-21', 0], ['2023-11-22', 1], ['2023-11-24', 0],
['2023-11-27', 0], ['2023-11-28', 0], ['2023-11-29', 0],
['2023-11-30', 0], ['2023-12-01', 0], ['2023-12-04', 0],
['2023-12-05', 1], ['2023-12-06', 1] , ['2023-12-07', 1],
['2023-12-08', 1], ['2023-12-11', 0], ['2023-12-12', 0],
['2023-12-13', 1], ['2023-12-14', 1], ['2023-12-15', 0],
['2023-12-18', 0], ['2023-12-19', 0], ['2023-12-20', 0]]
df = pd.DataFrame(data, columns=['date', 'sold'])
print(find_streaks(df))
返回
[[12, 19]]
,您确定的连胜。
要在 Pandas 中查找可容忍中断的连续情况,您可以使用
.shift()
和 .cumsum()
对连续销售进行分组。首先,确定销售天数的变化。然后,为这些更改创建组。通过允许连续无销售的特定天数来应用容忍级别。对于您的情况,请使用 df['sold'].ne(df['sold'].shift()).cumsum()
创建条纹组,然后根据您的容差标准进行过滤并选择所需的行。请记住,您将根据您的具体需求调整容差级别,这可能涉及对分组数据进行更多操作。