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

#python #pandas #loops #numpy

#python #pandas #циклы #numpy

Вопрос:

рассмотрим приведенный ниже фрейм данных

 df = pd.DataFrame({'date': ['03/06/19','03/06/19','03/07/19','03/07/19','03/08/19','03/08/19'], 'Column_1': ['a_id',0.1,'a_id',0.1,'b_id',0.15],
         'Column_2':['b_id',0.15,'b_id',0.15,'c_id',0.2]})

print(df)

    date    Column_1    Column_2
0   03/06/19    a_id    b_id
1   03/06/19    0.1     0.15
2   03/07/19    a_id    b_id
3   03/07/19    0.1     0.15
4   03/08/19    b_id    c_id
5   03/08/19    0.15    0.2
  

Проблема с этими данными, полученными извне, заключается в следующем: расположение элементов не согласовано. например, ‘b_id’ и ‘c_id’, приведенные выше, объединены в один столбец.

Я хочу очистить этот формат, чтобы я мог получать выходные данные в формате ниже

 out = pd.DataFrame({'date':['03/06/19','03/07/19','03/08/19'], 'a_id':[0.1,0.1,np.nan],'b_id':[0.15,0.15,0.15],'c_id':[0.2,np.nan,np.nan]})

print(out)
     date      a_id  b_id   c_id
0   03/06/19    0.1  0.15   0.2
1   03/07/19    0.1  0.15   NaN
2   03/08/19    NaN  0.15   NaN
  

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

Вот мое (очень непитоническое) решение:

 temp = df.T

temp2 = temp.iloc[:,0:2]

temp2 = temp2.set_index(temp2.iloc[:,0], drop=True)

temp3 = temp.iloc[:,2:4]

temp3 = temp3.set_index(temp3.iloc[:,0], drop=True)

temp2 = pd.merge(left=temp2, right=temp3, left_index=True, right_index=True, how='outer')

**# repeat process in a loop!**
temp3 = temp.iloc[:,4:6]

temp3 = temp3.set_index(temp3.iloc[:,0], drop=True)

temp2 = pd.merge(left=temp2, right=temp3, left_index=True, right_index=True, how='outer')

**# clean the final database!**
out = pd.DataFrame(pd.to_numeric(np.hstack(temp2.values), errors='coerce')
         .reshape(temp2.shape), columns=temp2.columns, index=temp2.index).dropna(how='all', axis=1)


print(out.T)

            a_id    b_id    c_id
 date           
 03/06/19   0.1     0.15    NaN
 03/07/19   0.1     0.15    NaN
 03/08/19   NaN     0.15    0.2
  

Ответ №1:

Продолжая ваш пример:

 x = df.to_numpy()
columns=['date', 'a_id', 'b_id', 'c_id']
pd.DataFrame([{'date': a[0], a[1] : b[1], a[2] : b[2]}for a, b in zip(x[0::2], x[1::2])], columns=columns)
  

дает:

     date    a_id    b_id    c_id
0   03/06/19    0.1 0.15    NaN
1   03/07/19    0.1 0.15    NaN
2   03/08/19    NaN 0.15    0.2
  

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

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