Заполнить строки значениями по умолчанию, если определено ограничение для столбцов данных - PullRequest
3 голосов
/ 03 июля 2019

Мне нужно заполнить строки значением по умолчанию =1 в DataFrame на основе информации в столбцах Start и Finish.
Таким образом, предел для заполнения разделенных столбцов в строке определяется на основе ['Start', 'Finish'].

DataFrame, df1:

ID  Car       Jan17     Jun18  Dec18  Apr19   Start   Finish                           
0   Nissan     0.0       1.7    3.7    0.0    Jun18   Dec18   
1   Porsche    10.0      0.0    2.8    3.5    Jan17   Apr19 
2   Golf       0.0       1.7    3.0    2.0    Jun18   Apr19 
3   Toyota     1.0       0.0    3.0    5.2    Jan17   Apr19 
4   Mazda      0.0       0.0    3.0    4.2    Dec18   Apr19
5   Mercedes   0.0       0.0    0.0    7.2    Apr19   Apr19
6   Passat     0.0       3.0    0.0    0.0    Jun18   Jun18

Например, если есть строка # 0: Start = Jun18 и Finish = Dec18.

Значения в строке # 0 должны быть заполнены на 1 для столбцов, начиная с Jun18 до Dec18.

Я пытался использовать функцию numpy.sign(), но естьневерный результат в случае, если 0.0 находится между двумя ненулевыми значениями.

Ожидаемый результат df2:

ID  Car       Jan17     Jun18  Dec18  Apr19   Start   Finish                           
0   Nissan     0.0       1.0    1.0    0.0    Jun18   Dec18   
1   Porsche    1.0       1.0    1.0    1.0    Jan17   Apr19 
2   Golf       0.0       1.0    1.0    1.0    Jun18   Apr19 
3   Toyota     1.0       1.0    1.0    1.0    Jan17   Apr19 
4   Mazda      0.0       0.0    1.0    1.0    Dec18   Apr19
5   Mercedes   0.0       0.0    0.0    1.0    Apr19   Apr19
6   Passat     0.0       1.0    0.0    0.0    Jun18   Jun18

1 Ответ

3 голосов
/ 03 июля 2019

get_dummies + interpolate

Для этого требуется, чтобы ваши столбцы сортировались по времени, и в идеале, чтобы начало и конец всегда присутствовали в именах столбцов.

df = df.set_index(['ID', 'Car', 'Start', 'Finish'])

s1 = (pd.get_dummies(df.index.get_level_values('Start'))
        .reindex(df.columns, axis=1)
        .replace(0, np.NaN))
s2 = (pd.get_dummies(df.index.get_level_values('Finish'))
        .reindex(df.columns, axis=1)
        .replace(0, np.NaN))

res = s1.combine_first(s2).interpolate(axis=1, limit_area='inside').fillna(0, downcast='infer')
res.index = df.index
res = res.reset_index()

Вывод res:

   ID       Car  Start Finish  Jan17  Jun18  Dec18  Apr19
0   0    Nissan  Jun18  Dec18      0      1      1      0
1   1   Porsche  Jan17  Apr19      1      1      1      1
2   2      Golf  Jun18  Apr19      0      1      1      1
3   3    Toyota  Jan17  Apr19      1      1      1      1
4   4     Mazda  Dec18  Apr19      0      0      1      1
5   5  Mercedes  Apr19  Apr19      0      0      0      1
6   6    Passat  Jun18  Jun18      0      1      0      0

В случае, когда Start и Finish уже получены из самих данных (кажется, это первый и последний ненулевые столбцы), вы можете пропустить все пустышки и использовать where вместо оригинальный DataFrame.

df = df.set_index(['ID', 'Car', 'Start', 'Finish'])
res = (df.where(df.ne(0))
         .clip(1,1)
         .interpolate(axis=1, limit_area='inside')
         .fillna(0, downcast='infer')
         .reset_index())
...