#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. прекрасное решение. Я просто выясню, как это будет работать с гораздо большим фреймом данных (приведенный выше пример был просто репрезентативной выборкой), прежде чем я приму этот ответ.