Как преобразовать матрицу 183,223,040x4 в 140 матриц с размерами 1145x1145 без MemoryError? - PullRequest
0 голосов
/ 25 марта 2019

У меня есть матрица размеров 183,223,040x4 с переменными, показанными ниже. В 'REG' имеется 140 разных значений, а в 'SAMAC' и 'SAMAC.1' 1145 разных значений

Я хочу перебрать REG, чтобы получить 140 матриц размера 1145 * 1145 с правильным значением 'VALUE'.

Я пробовал следующее:

- петля над странами

- создать пустую матрицу 1145 * 1145, проиндексированную с помощью SAMAC и с именами столбцов SAMAC.1

- переходить строка за строкой текущего фрейма данных

- проверить значение SAMAC (строки) и SAMAC.1 (столбцы)

- расположить SAMAC и SAMAC.1 в пустой матрице и присвоить им соответствующее ЗНАЧЕНИЕ

import pandas as pd
import dask.dataframe as dd

all_sam=dd.read_csv(r'C:\GP2\all_sams_trial.csv',skiprows=1)

all_sam.head()
   SAMAC SAMAC.1  REG  Value
0  m_pdr   m_pdr  aus    0.0
1  m_wht   m_pdr  aus    0.0
2  m_gro   m_pdr  aus    0.0
3  m_v_f   m_pdr  aus    0.0
4  m_osd   m_pdr  aus    0.0

countries=list(all_sam["REG"].unique().compute())
col_names=list(all_sam["SAMAC"].unique().compute())

for country in countries:
    df=pd.DataFrame(0,index=col_names,columns=col_names)

    sam=all_sam[all_sam["REG"]==country].compute()

    for index,row in sam.iterrows():
        row_index=str(row["SAMAC"])
        col_index=str(row["SAMAC.1"])
        df.loc[row_index,col_index]=row['Value']
        print(index)

    df.to_csv(country+"_SAM.csv")

Проблема в том, что для вычисления требуется много времени (около 2 дней). Есть ли способ ускорить это?

1 Ответ

0 голосов
/ 25 марта 2019

Обновление 1: После понимания проблемы медленных вычислений в OP из-за большого размера информационного кадра, вот обновление.

  1. Проверьте dtypes столбцов, используя all_sam.dtypes, и размер (в Мб) вашего фрейма данных, используя:

    all_sam.memory_usage(deep=True) / 1024 ** 2
    
  2. Подумайте об изменении имени столбца 'SAMAC.1' на 'SAMAC_1', так как это может вызвать ошибку в следующих строках. Перед обработкой измените dtypes для «REG», «SAMAC» и «SAMAC_1» на «категорические»:

    all_sam.REG = all_sam.REG.astype('category')
    all_sam.SAMAC = all_sam.SAMAC.astype('category')
    all_sam.SAMAC_1 = all_sam.SAMAC_1.astype('category')
    
  3. В зависимости от ваших требований вы можете уменьшить dtype столбца «Значение» до float16, int16, int8 и т. Д., Используя следующий код:

    all_sam.Value = all_sam.Value.astype('float16')
    
  4. Проверьте размер еще раз.

    all_sam.memory_usage(deep=True) / 1024 ** 2
    

Надеюсь, это позволит ускорить вычисления.

Ссылка: vs.datascience.com

Я взял небольшой примерный фрейм данных, чтобы найти решение вашей проблемы.

import pandas as pd
import numpy as np

df = pd.DataFrame( {'REG':['A','A','A','A','A','A','B','B','B','B','B','B'], 'SAMAC1':['a','a','a','b','b','b','c','c','c','d','d','d'], 'SAMAC':['p','q','r','p','q','r','p','q','r','p','q','r'], 'value':[0,0,0,0,0,0,0,0,0,0,0,0]})
array_ = df[['REG','SAMAC1','SAMAC']].values.transpose()
index = pd.MultiIndex.from_arrays(array_, names=('REG', 'SAMAC1','SAMAC'))
df2 = df['value']
df2.index=index
country_labels = df2.index.get_level_values(0)
country_unique = country_labels.unique()
result_arr = []
for c in country_unique:
    df3 = df2[df2.index.get_level_values(0) == c]
    result_arr.append(df3.unstack().values)
result_arr = np.array(result_arr)
print(result_arr.shape)

Выход: (2,2,3)

...