pandas манипулирование кадрами без использования цикла - PullRequest
0 голосов
/ 20 февраля 2020

Пожалуйста, найдите ниже вход и выход. В соответствии с каждым идентификатором магазина и идентификатором периода, 11 элементов должны присутствовать, если какой-либо элемент отсутствует, добавьте его и заполните эту строку 0 без использования l oop.

Любая помощь высоко ценится.

вход

enter image description here

Ожидаемый выход

enter image description here

Ответы [ 3 ]

1 голос
/ 20 февраля 2020

Вы можете сделать это:

Образец DF :

df = pd.DataFrame({'store_id':[1160962,1160962,1160962,1160962,1160962,1160962,1160962,1160962,1160962,1160962, 1160962],
                   'period_id':[1025,1025,1025,1025,1025,1025,1026,1026,1026,1026,1026],
                   'item_x':[1,4,5,6,7,8,1,2,5,6,7],
                  'z':[1,4,5,6,7,8,1,2,5,6,7]})

Решение:

num = range(1,12)
def f(x):
    return x.reindex(num, fill_value=0)\
                   .assign(store_id=x['store_id'].mode()[0], period_id = x['period_id'].mode()[0])

df.set_index('item_x').groupby(['store_id','period_id'], group_keys=False).apply(f).reset_index()
1 голос
/ 20 февраля 2020

Вы можете сделать:

from itertools import product

pdindex=product(df.groupby(["store_id", "period_id"]).groups, range(1,12))

pdindex=pd.MultiIndex.from_tuples(map(lambda x: (*x[0], x[1]), pdindex), names=["store_id", "period_id", "Item"])

df=df.set_index(["store_id", "period_id", "Item"])

res=pd.DataFrame(index=pdindex, columns=df.columns)

res.loc[df.index, df.columns]=df

res=res.fillna(0).reset_index()

Теперь это будет работать только при условии, что у вас нет Item вне диапазона [1,11].

0 голосов
/ 21 февраля 2020

Это упрощение правильного ответа @ GrzegorzSkibinski.

Этот ответ не изменяет оригинальный DataFrame. Он использует меньше переменных для хранения промежуточных структур данных и использует понимание списка, чтобы упростить использование карты.

Я также использую reindex() вместо того, чтобы создавать новый DataFrame с использованием сгенерированного индекса и заполнять его исходные данные.

import pandas as pd
import itertools

df.set_index(
    ["store_id", "period_id", "Item_x"]
).reindex(
    pd.MultiIndex.from_tuples([
        group + (item,)
        for group, item in itertools.product(
            df.groupby(["store_id", "period_id"]).groups, 
            range(1, 12),
        )],
        names=["store_id", "period_id", "Item_x"]
    ),
    fill_value=0,
).reset_index()

При тестировании выходной сигнал соответствовал ожидаемому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...