У меня есть фрейм данных с двумя столбцами, которые представляют размерность X и Y двумерного массива, который необходимо создать. Значение в 2D-массиве будет поступать из другого столбца в фрейме данных. Если в фрейме данных имеется более 1 столбца значений, необходимо создать такое же количество 2D-списков.
До сих пор мне удалось создать 1 2D-список, предполагая, что в фрейме данных есть только 1 столбец значений. Я создал пустой 2D-список того же размера на основе столбцов X и Y в фрейме данных. Затем я перебираю каждую строку фрейма данных и заполняю 2D-список на основе значения X и Y в этой строке.
Пример кадра данных. X представляет «столбцы» 2D-списка, а Y представляет «строки» 2D-списка. В этом случае 2D-список имеет размер 3x2. Столбец (numeric_result, voltage) заполнит 2D-список.
| parent | child | numeric_result | X | Y |
index | | voltage |
0 | xy | a | 1.2 | 1 | 1 |
1 | xy | a | 1.1 | 2 | 1 |
2 | xy | a | 1.2 | 3 | 1 |
3 | xy | a | 1.1 | 1 | 2 |
4 | xy | a | 1.0 | 2 | 2 |
5 | xy | a | 1.3 | 3 | 2 |
Сначала я создаю 2D-список:
rows = 2
cols = 3
def make2dList(rows, cols):
a=[]
for row in range(rows): a += [[0]*cols]
return a
list2d = make2dList(rows, cols)
Затем я заполняю список.
def fill2dlist(a, dataframe):
# Loop through each row of dataframe
for i in range(len(dataframe.index)):
col = int(dataframe.iloc[i].X)
row = int(dataframe.iloc[i].Y)
a[row-1][col-1] = (pd.to_numeric(dataframe.loc[i,'numeric_result'].values[0]))
return a
finallist = modify2dlist(list2d, dataframe)
print(finallist)
[[1.2, 1.1, 1.2],[1.1, 1.0, 1.3]]
Это кажется неэффективным. Есть ли способ векторизовать это или как-то ускорить?
Кроме того, я хочу создать новый фрейм данных, как показано ниже, где есть много комбинаций родительского и дочернего элементов. Будем признательны за любую помощь в том, как создать этот фреймворк данных. Спасибо!
| parent | child | numeric_result_list |
index | | voltage |
0 | xy | a | [[1.2, 1.1, 1.2], [1.1, 1.0, 1.3]] |
1 | xy | b | [[1.1, 1.0, 1.1], [1.4, 1.3, 1.5]] |
2 | xy | c | [[1.1, 1.0, 1.6], [1.4, 1.8, 1.5]] |
3 | yz | e | [[1.4, 1.2, 1.2], [1.7, 1.2, 1.0]] |
Отредактируйте здесь мой код для создания фрейма данных с 2D-списком. Любая помощь будет оценена по достоинству, чтобы сделать его эффективным.
# Create an empty dataframe with column names
dffinal = pd.DataFrame(columns=['parent','child','numeric_result_list'])
# Group by 'parent' and 'child'
parent_child = df2.groupby(['parent', 'child'])
i = 1
for name, group in parent_child:
print('Processing: ', name)
group = group.reset_index(drop=True)
_array2d_ = make2dList(rows, cols)
_array2d_ = modify2dlist(_array2d_, _group_)
dffinal.loc[i] = [name[0], name[1], _array2d_]
i = i+1
print('done')
dff = dff.reset_index(drop=True)






Я упростил процесс генерации 2D-списка, используя мультииндексацию.
yarray = np.arange(min(df.Y),max(df.Y)+1,1)
xarray = np.arange(min(df.X),max(df.X)+1,1)
idx = pd.MultiIndex.from_product([yarray, xarray], names=['Y', 'X'])
idx дает все декартовы комбинации Y и X. Затем я использую idx для индексации фрейма данных. Ниже код также заполняет NaN в таких столбцах, как родительский и дочерний, чего я пытаюсь выяснить, как избежать.
# https://stackoverflow.com/questions/43688938/pandas-insert-rows-where-data-is-missing$
df1 = df.set_index(['Y', 'X']).reindex(idx)
# https://stackoverflow.com/questions/38134012/pandas-dataframe-fillna-only-some-columns-in-place$
df1['numeric_result'] = df1['numeric_result'].fillna(value=0)
Прежде чем использовать numpy reshape, я сортирую фрейм данных, используя индексы Y и X.
df1= df1.sort_values(by=['Y','X'])
array = np.reshape(df1.numeric_result.values, (len(yarray,len(xarray)))