- Первый Функция пытается получить среднее значение строк с совпадающими значениями в кластере, группе и дате.
- Вторая функция снова анализирует ее, на этот раз группируя по кластеру, группе и периоду.
- Третья функция вместо этого использует построчный подход в отношении кода города и группы, при этом всякий раз, когда в «Значениях» обнаруживается нулевое значение, скрипт ищет первое ненулевое значение в этой группе перед ним и первая ненулевая функция после нее, также по дате, принимает среднее значение из двух.
Исходный
Дата
Значение
45443
10
45444
0
45445
0
45446
15
Первый анализ
Дата
Значение
45443
10
45444
12,5
45445
0
45446
15
Второй анализ
Дата
Значение
45443
10
45444
12,5
45445
13,75
45446
15< /td>
Однако, хотя исходные функции, кажется, выполняют свою задачу, третья, похоже, ничего не исправляет при каждом анализе, как следует из журнала.
Стоит отметить: первые две функции должны выполняться только один раз, в то время как третья функция должна выполнять цикл до тех пор, пока все не будет «очищено».
Я прикрепил рассматриваемый код здесь:
import pandas as pd
import numpy as np
import logging
# Sample data creation
np.random.seed(0)
data = {
'Area_Code': ['AA', 'AA', 'AA', 'AA', 'AA', 'AA', 'AA', 'AA', 'AA', 'AA'],
'Date': [pd.Timestamp('2023-01-01').toordinal() + i for i in range(10)],
'Group': ['G1', 'G1', 'G1', 'G1', 'G1', 'G2', 'G2', 'G2', 'G2', 'G2'],
'PERIOD_NAME': ['P1', 'P1', 'P1', 'P1', 'P1', 'P2', 'P2', 'P2', 'P2', 'P2'],
'CLUSTER': ['C1', 'C1', 'C1', 'C1', 'C1', 'C2', 'C2', 'C2', 'C2', 'C2'],
'Value': [100, 0, 0, 200, 0, 0, 300, 0, 0, 400]
}
df = pd.DataFrame(data)
# Function to replace zero values by looking at the date above and the date below
def replace_zeros_with_neighbors(df):
logging.info("Starting to replace remaining zeros by looking at neighbors.")
zeros_fixed = 0
for index, row in df.iterrows():
if row['Value'] == 0:
area_code = row['Area_Code']
group = row['Group']
date = row['Date']
prev_row = df[(df['Area_Code'] == area_code) &
(df['Group'] == group) &
(df['Date'] < date) &
(df['Value'] != 0)].sort_values(by='Date').tail(1)
next_row = df[(df['Area_Code'] == area_code) &
(df['Group'] == group) &
(df['Date'] > date) &
(df['Value'] != 0)].sort_values(by='Date').head(1)
if not prev_row.empty and not next_row.empty:
avg_value = (prev_row['Value'].values[0] + next_row['Value'].values[0]) / 2
df.at[index, 'Value'] = avg_value
zeros_fixed += 1
elif not prev_row.empty:
df.at[index, 'Value'] = prev_row['Value'].values[0]
zeros_fixed += 1
elif not next_row.empty:
df.at[index, 'Value'] = next_row['Value'].values[0]
zeros_fixed += 1
logging.info(f"Completed neighbor-based zero replacement. Fixed {zeros_fixed} zeros.")
return df, zeros_fixed
# Function to iteratively replace zero values until there are no zeros left
def iterative_replace_zeros(df):
logging.info("Starting iterative zero replacement.")
df, zeros_fixed = replace_zeros_with_neighbors(df)
total_zeros_fixed = zeros_fixed
remaining_zeros = (df['Value'] == 0).sum()
logging.info(f"Initial pass: Fixed {zeros_fixed} zeros. {remaining_zeros} zeros remaining.")
while remaining_zeros > 0:
df, zeros_fixed = replace_zeros_with_neighbors(df)
total_zeros_fixed += zeros_fixed
remaining_zeros = (df['Value'] == 0).sum()
logging.info(f"Fixed {zeros_fixed} zeros in this loop. {remaining_zeros} zeros remaining.")
logging.info(f"Completed iterative zero replacement. Total zeros fixed: {total_zeros_fixed}.")
return df
# Example usage
logging.basicConfig(level=logging.INFO)
df = iterative_replace_zeros(df)
print(df)
Подробнее здесь: https://stackoverflow.com/questions/789 ... -satisfied