как найти недостающую пару в фрейме данных pandas и заполнить фиктивным значением

#python #pandas

#python #pandas

Вопрос:

Здесь у меня есть фиктивный фрейм данных:

 import pandas as pd

df = pd.DataFrame({'Date':[2019-08-06,2019-08-08,2019-08-01,2019-10-12], 'Name':['A','A','B','C'], 'Type':['X','Y','Y','Z']})
  

Существует 3 потенциальных значения для Type — W, X, Y, Z
Я хочу найти недостающую пару для Name Type и заполнить вставить строку значением даты ‘ 0000-00-00'

Итак, в этом примере все A, B, C не имеют типа W / B, а C не имеет X / C не имеет Y / A, а B не имеет Z

Поэтому мне придется добавить 8 строк с датой 0000-00-00

В качестве резюме, что мне нужно сделать, это —

Найдите недостающие пары из двух столбцов и заполните другую конкретную строку фиктивным значением.

РЕДАКТИРОВАТЬ — Поскольку я обнаружил ошибку ValueError с помощью приведенных ниже решений, я отредактировал фиктивный фрейм данных.

 import pandas as pd

df = pd.DataFrame({'Date':[2019-08-06,2019-08-07,2019-08-08,2019-08-01,2019-10-12], 'Name':['A','A','A','B','C'], 'Type':['X','X','Y','Y','Z']})
  

Комментарии:

1. ваши данные не загружаются. `начальные нули в десятичных целочисленных литералах не допускаются; используйте префикс 0o для восьмеричных целых чисел`

2. «Существует 3 потенциальных значения для типа — W, X, Y, Z», это 4, а не 3.

Ответ №1:

Использовать MultiIndex.from_product по уровням из всех комбинаций из столбцов, MultiIndex.levels переданных в DataFrame.reindex :

 df = df.set_index(['Name','Type'])

df = df.reindex(pd.MultiIndex.from_product(df.index.levels), fill_value='0000-00-00')
print (df)
                 Date
Name Type            
A    X     2019-08-06
     Y     2019-08-08
     Z     0000-00-00
B    X     0000-00-00
     Y     2019-08-01
     Z     0000-00-00
C    X     0000-00-00
     Y     0000-00-00
     Z     2019-10-12
     
  

РЕДАКТИРОВАТЬ: ошибка ValueError:cannot handle a non-unique multi-index! означает, что в , , есть дублированные пары Name , Type , решение для обработки данных:

 df = pd.DataFrame({'Date':['2019-08-06','2019-08-08','2019-08-01','2019-10-12'], 
                   'Name':['A','A','B','C'], 
                   'Type':['X','X','Y','Z'], 
                   'col':list('abcd')})

print (df)
         Date Name Type col
0  2019-08-06    A    X   a
1  2019-08-08    A    X   b <-duplicated pair `A, X` - Name, Type
2  2019-08-01    B    Y   c
3  2019-10-12    C    Z   d
  

Решение заключается в том, чтобы сначала удалить дубликаты DataFrame.duplicated , применить reindex для всех комбинаций:

 mask = df.duplicated(['Name','Type'])
df1 = df[~mask].set_index(['Name','Type'])

df1 = (df1.reindex(pd.MultiIndex.from_product(df1.index.levels))
          .fillna({'Date':'0000-00-00', 'col':'missing'}).reset_index())
print (df1)
  Name Type        Date      col
0    A    X  2019-08-06        a
1    A    Y  0000-00-00  missing
2    A    Z  0000-00-00  missing
3    B    X  0000-00-00  missing
4    B    Y  2019-08-01        c
5    B    Z  0000-00-00  missing
6    C    X  0000-00-00  missing
7    C    Y  0000-00-00  missing
8    C    Z  2019-10-12        d
  

И, наконец, добавьте все дублированные строки с помощью concat :

 df = pd.concat([df1, df[mask]]).sort_values(['Name','Type'], ignore_index=True)
print (df)
  Name Type        Date      col
0    A    X  2019-08-06        a
1    A    X  2019-08-08        b
2    A    Y  0000-00-00  missing
3    A    Z  0000-00-00  missing
4    B    X  0000-00-00  missing
5    B    Y  2019-08-01        c
6    B    Z  0000-00-00  missing
7    C    X  0000-00-00  missing
8    C    Y  0000-00-00  missing
9    C    Z  2019-10-12        d
  

Комментарии:

1. Предполагается, что Name и Type являются категориальными столбцами с соответствующими уровнями, в противном случае вам нужно преобразовать его. Также это похоже на мое 😉

2. @jezrael Спасибо, что, если столбцов больше, а я хочу заполнить значение только в столбце даты?

3. @jezrael Я получил ошибку ValueError: невозможно обработать неуникальный мультииндекс!

4. @YunTaeHwang — Ошибка означает, что существует некоторая комбинация Name и Type 2 или более дат, например, если сначала изменить Y на X , то какой должен быть ожидаемый результат? Удалена вторая A, X строка, потому что дублируется?

5. @YunTaeHwang — я думаю, что если данные df = pd.DataFrame({'Date':['2019-08-06','2019-08-08','2019-08-01','2019-10-12'], 'Name':['A','A','B','C'], 'Type':['X','X','Y','Z'], 'col':list('abcd')})