Создание нескольких фреймов данных с помощью функции L oop & - PullRequest
0 голосов
/ 29 мая 2020

У меня есть df более 1 млн строк, подобных этому

ID  Date    Amount
x   May 1   10
y   May 2   20
z   May 4   30
x   May 1   40
y   May 1   50
z   May 2   60
x   May 1   70
y   May 5   80
a   May 6   90
b   May 8   100
x   May 10  110

Мне нужно отсортировать данные по дате, а затем создать новые фреймы данных в зависимости от того, сколько раз значение присутствует в столбце Amount. Итак, если x совершил покупку 3 раза, мне нужно, чтобы она была в 3 разных фреймах данных. Фрейм данных first_purchase будет иметь каждый идентификатор, который был приобретен хотя бы один раз, независимо от даты или суммы. Если ID покупается 3 раза, мне нужно, чтобы этот ID был в первой покупке, затем во второй, а затем в третьей с датой и суммой.

Сделать это вручную легко: -

df = df.sort_values('Date')
first_purchase = df.drop_duplicates('ID')
after_1stpurchase = df[~df.index.isin(first_purchase.index)]

второй фрейм данных будет создан с помощью: -

after_1stpurchase = after_1stpurchase.sort_values('Date')
second_purchase = after_1stpurchase.drop_duplicates('ID')
after_2ndpurchase = after_1stpurchase[~after_1stpurchase.index.isin(second_purchase.index)]

Как мне создать l oop, чтобы предоставить мне каждый фрейм данных?

1 Ответ

1 голос
/ 29 мая 2020

IIU C, мне удалось добиться желаемого.

import pandas as pd
import numpy as np

# source data for the dataframe
data = {
"ID":["x","y","z","x","y","z","x","y","a","b","x"],
"Date":["May 01","May 02","May 04","May 01","May 01","May 02","May 01","May 05","May 06","May 08","May 10"],
"Amount":[10,20,30,40,50,60,70,80,90,100,110]
}

df = pd.DataFrame(data)

# convert the Date column to datetime and still maintain the format like "May 01"
df['Date'] = pd.to_datetime(df['Date'], format='%b %d').dt.strftime('%b %d')

# sort the values on ID and Date
df.sort_values(by=['ID', 'Date'], inplace=True)
df.reset_index(inplace=True, drop=True)

print(df)

Исходный фрейм данных:

    Amount    Date ID
0       90  May 06  a
1      100  May 08  b
2       10  May 01  x
3       40  May 01  x
4       70  May 01  x
5      110  May 10  x
6       50  May 01  y
7       20  May 02  y
8       80  May 05  y
9       60  May 02  z
10      30  May 04  z

.

# create a list of unique ids
list_id = sorted(list(set(df['ID'])))

# create an empty list that would contain dataframes
df_list = []

# count of iterations that must be seperated out
# for example if we want to record 3 entries for 
# each id, the iter would be 3. This will create
# three new dataframes that will hold transactions
# respectively. 
iter = 3
for i in range(iter):
    df_list.append(pd.DataFrame())


for val in list_id:
    tmp_df = df.loc[df['ID'] == val].reset_index(drop=True)

    # consider only the top iter(=3) values to be distributed
    counter = np.minimum(tmp_df.shape[0], iter)
    for idx in range(counter):
        df_list[idx] = df_list[idx].append(tmp_df.loc[tmp_df.index == idx])

for df in df_list:
    df.reset_index(drop=True, inplace=True)
    print(df)

Транзакция 1:

   Amount    Date ID
0      90  May 06  a
1     100  May 08  b
2      10  May 01  x
3      50  May 01  y
4      60  May 02  z

Транзакция 2:

   Amount    Date ID
0      40  May 01  x
1      20  May 02  y
2      30  May 04  z

Транзакция №3:

   Amount    Date ID
0      70  May 01  x
1      80  May 05  y

Обратите внимание, что в ваших данных есть четыре транзакции для 'x'. Допустим, вы хотели отслеживать и 4-ю итеративную транзакцию. Все, что вам нужно сделать, это изменить значение if 'iter' на 4, и вы также получите четвертый фрейм данных со следующим значением:

   Amount    Date ID
0     110  May 10  x
...