Например, в случае с тремя пользователями A, B и C, если A и B если все три пользователя активны одновременно, в столбцах A, B, C будет 1, а остальное будет 0.
В моем реальном случае столбцов много, поэтому экспоненциальная стоимость функции делает ее непомерно высокой. Я пытался создать код, который ищет группы, которые никогда не совпадают, чтобы избежать создания избыточных столбцов. Например, если B и C никогда не имеют общей строки со значением 1, нет смысла создавать столбцы B,C или A,B,C.
Я попробовал использовать GitHub Copilot, но он не смог предоставить полезного решения. Может ли кто-нибудь помочь мне оптимизировать мой код?
Вот код, который я использую:
Код: Выделить всё
def process_dataframe_opt2(df):
# List of columns for combinations, excluding 'fecha_hora'
columns = [col for col in df.columns if col != 'fecha_hora']
# Generate all possible combinations of the columns
for r in range(1, len(columns) + 1):
for comb in combinations(columns, r):
col_name = ','.join(comb)
df[col_name] = df[list(comb)].all(axis=1).astype(int)
# Create a copy of the original DataFrame to modify it
df_copy = df.copy()
# Process combinations from largest to smallest
for r in range(len(columns), 1, -1):
for comb in combinations(columns, r):
col_name = ','.join(comb)
active_rows = df[col_name] == 1
if active_rows.any():
for sub_comb in combinations(comb, r-1):
sub_col_name = ','.join(sub_comb)
df_copy.loc[active_rows, sub_col_name] = 0
# Remove columns that only contain 0
df_copy = df_copy.loc[:, (df_copy != 0).any(axis=0)]
return df_copy
Код: Выделить всё
import pandas as pd
from itertools import combinations
# Create a range of time
date_rng = pd.date_range(start='2024-05-13 15:52:00', end='2024-05-13 16:04:00', freq='min')
# Create an empty DataFrame
df = pd.DataFrame(date_rng, columns=['fecha_hora'])
# Add the login columns with corresponding values
df['A'] = 1 # Always active
df['B'] = [1] * 6 + [0] * 5 + [1] * 2 # Active in the first 6 intervals
df['C'] = [1] * 5 + [0] * 6 + [1] * 2 # Active in the first 5 intervals
df['D'] = [1] * 4 + [0] * 7 + [1] * 2 # Active in the first 4 intervals
df['E'] = [1] * 3 + [0] * 3 + [1] * 2 + [0] * 3 + [1]*2 # Active in two blocks
df['F'] = [0] * 7 + [1] * 3 + [0] * 3 # Active in a single block towards the end
df['alfa'] = [0] * 10 + [1] * 1 + [0] * 2
# Adjust some rows to have more than one '1'
df.loc[1, ['A', 'B', 'C']] = 1 # Row with multiple '1's
df.loc[8, ['D', 'E', 'F']] = 1 # Another row with multiple '1's
df_copy = process_dataframe_opt2(df)
Подробнее здесь: https://stackoverflow.com/questions/787 ... ith-pandas