#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')})