Предположим, у меня есть 4 небольших DataFrames
df1
, df2
, df3
Иdf4
import pandas as pd
из импорта functools уменьшает
импорт numpy как np
df1 = pd . DataFrame ([[ 'a' , 1 , 10 ], [ 'a' , 2 , 20 ], [ 'b' , 1 , 4 ], [ 'c' , 1 , 2 ], [ 'e' , 2 , 10 ]])
df2 = pd . DataFrame ([[ 'a' , 1 , 15 ], [ 'a' , 2 , 20 ], [ 'c' , 1 , 2 ]])
df3 = pd . DataFrame ([[ 'd' , 1 , 10 ], [ 'e' , 2 , 20 ], [ 'f' , 1 , 1 ]])
df4 = pd . DataFrame ([[ 'd' , 1 , 10 ], [ 'e' , 2 , 20 ], [ 'f' , 1 , 15 ]])
df1 . columns = [ 'name' , 'id' , 'price' ]
df2 . columns = [ 'name' , 'id' , 'price' ]
df3 . columns = [ 'name' , 'id' , 'price' ]
df4 . columns = [ 'name' , 'id' , 'price' ]
df1 = df1 . rename ( columns = { 'price' : 'pricepart1' })
df2 = df2 . rename ( columns = { 'price' : 'pricepart2' })
df3 = df3 . rename ( columns = { 'price' : 'pricepart3' })
df4 = df4 . rename ( columns = { 'price' : 'pricepart4' }) prettyprinted "># Merge dataframes
df = pd.merge(df1, df2, left_on=['name', 'id'], right_on=['name', 'id'], how='outer')
df = pd.merge(df , df3, left_on=['name', 'id'], right_on=['name', 'id'], how='outer')
df = pd.merge(df , df4, left_on=['name', 'id'], right_on=['name', 'id'], how='outer')
# Fill na values with 'missing'
df = df.fillna('missing')
Создание выше - это 4 DataFrames, я бы хотел, чтобы это было в коде ниже.
from functools import reduce
import pandas as pd
import numpy as np
dfList = []
#To create the 48 DataFrames of size 62245 X 3
for i in range(0, 49):
dfList.append(pd.DataFrame(np.random.randint(0,100,size=(62245, 3)), columns=['name', 'id', 'pricepart' + str(i + 1)]))
#The solution I came up with to extend the solution to more than 3 DataFrames
df_merged = reduce(lambda left, right: pd.merge(left, right, left_on=['name', 'id'], right_on=['name', 'id'], how='outer'), dfList).fillna('missing')
Таким образом, я достиг этих DataFrames MemoryError 4, у которых не так много строк и столбцов.
В принципе, я хочу расширить вышеупомянутое внешнее решение MemoryError до MULTIPLE (48) DataFrames размером 62245 X 3:
Поэтому я придумал это решение, построив из другого ответа StackOverflow, который использовал сокращение лямбда:
int64
Это вызывает a int64
.
Я не знаю, что делать, чтобы остановить ядро ??от смерти. Я застрял на этом в течение двух дней. Некоторый код для операции EXACT merge, который я выполнил, не вызывает того float64
или чего-то, что дает вам то же самое результат, был бы действительно оценен.
Кроме того , 3 колонки в главном DataFrame (не воспроизводимые 48 DataFrames в примере) имеют тип float64
, float16
и MemoryError
я предпочел бы им оставаться таким образом из-за целого числа и intermediatedfList = dfList tempdfList = [] #Until я сливаться все 48 кадров два за раз, пока он не станет размером 2 в то время как ( len ( intermediatedfList ) ! = 2 ): # Если есть четное число DataFrames, если len ( intermediatedfList )% 2 == 0 : #Go с шагом в два для i в диапазоне ( 0 , len ( intermediatedfList ), 2 ): #Merge DataFrame в индексе i, i + 1 df1 = pd . merge ( intermediatedfList [ i ], intermediatedfList [ i + 1 ], left_on = [ 'name' , 'id' ], right_on = [ 'name' , 'id' ], how = 'outer' ) print ( df1 . info ( memory_usage = 'deep' )) # Подключить его к этому списку tempdfList . append ( df1 ) #After DataFrames в промежуточном fList, объединяющем его по два за один раз с использованием вспомогательного списка tempdfList, #Set intermediatedfList, равный tempdfList, поэтому он может продолжить цикл while. intermedfList = tempdfList else : # Если есть нечетное число DataFrames, сохраните первый DataFrame out tempdfList = [ intermediatedfList [ 0 ]] #Go с шагом в два, начиная с 1 вместо 0 для i в диапазоне ( 1 , len ( промежуточное fList ) , 2 ): #Merge DataFrame в индексе i, i + 1 df1 = pd . merge ( intermediatedfList [ i ], intermediatedfList [ i + 1 ], left_on = [ 'name' , 'id' ], right_on = [ 'name' , 'id' ], how = 'outer' ) print ( df1 . info ( memory_usage = 'deep' )) tempdfList . append ( df1 ) #After DataFrames в промежуточном fList, объединяющем его по два за один раз с использованием вспомогательного списка tempdfList, #Set intermediatedfList, равный tempdfList, поэтому он может продолжить цикл while. intermediatedfList = tempdfList, который он представляет.
РЕДАКТИРОВАТЬ:
Вместо того, чтобы итеративно пытаться запускать операции слияния или использовать уменьшающие лямбда-функции, я сделал это в группах по 2! Кроме того, я изменил тип данных для некоторых столбцов, некоторые из них не обязательно MemoryError
. Поэтому я его спустил MemoryError
. Он становится очень далеко, но все еще заканчивается тем, что он бросает pd.concat
.
df_list = [df1, df2, ...]
for df in df_list:
df.set_index(['name', 'id'], inplace=True)
df = pd.concat(df_list, axis=1) # join='inner'
df.reset_index(inplace=True)
Есть ли способ оптимизировать мой код, чтобы избежать этого concat
, я даже использовал RAM AWS 192GB (теперь я должен им 7 $, который я мог бы дать одному из yall), который становится дальше, чем то, что я получил, и это все еще бросает join
после сокращения списка из 28 DataFrames до 4.