Mam dużą ramkę danych z 423244 liniami. Chcę podzielić to na 4. Próbowałem następującego kodu, który dał błąd?ValueError: array split does not result in an equal division
for item in np.split(df, 4):
print item
Jak podzielić tę ramkę danych na 4 grupy?
np.split(df, N)
funkcji, proszę.Odpowiedzi:
Zastosowanie
np.array_split
:Docstring: Split an array into multiple sub-arrays. Please refer to the ``split`` documentation. The only difference between these functions is that ``array_split`` allows `indices_or_sections` to be an integer that does *not* equally divide the axis.
In [1]: import pandas as pd In [2]: df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', ...: 'foo', 'bar', 'foo', 'foo'], ...: 'B' : ['one', 'one', 'two', 'three', ...: 'two', 'two', 'one', 'three'], ...: 'C' : randn(8), 'D' : randn(8)}) In [3]: print df A B C D 0 foo one -0.174067 -0.608579 1 bar one -0.860386 -1.210518 2 foo two 0.614102 1.689837 3 bar three -0.284792 -1.071160 4 foo two 0.843610 0.803712 5 bar two -1.514722 0.870861 6 foo one 0.131529 -0.968151 7 foo three -1.002946 -0.257468 In [4]: import numpy as np In [5]: np.array_split(df, 3) Out[5]: [ A B C D 0 foo one -0.174067 -0.608579 1 bar one -0.860386 -1.210518 2 foo two 0.614102 1.689837, A B C D 3 bar three -0.284792 -1.071160 4 foo two 0.843610 0.803712 5 bar two -1.514722 0.870861, A B C D 6 foo one 0.131529 -0.968151 7 foo three -1.002946 -0.257468]
źródło
array_split
zwraca listę DataFrames, więc możesz po prostu zapętlić listę ...AttributeError: 'DataFrame' object has no attribute 'size'
Chciałem zrobić to samo i miałem najpierw problemy z funkcją split, potem problemy z instalacją pand 0.15.2, więc wróciłem do mojej starej wersji i napisałem małą funkcję, która działa bardzo dobrze. Mam nadzieję, że to pomoże!
# input - df: a Dataframe, chunkSize: the chunk size # output - a list of DataFrame # purpose - splits the DataFrame into smaller chunks def split_dataframe(df, chunk_size = 10000): chunks = list() num_chunks = len(df) // chunk_size + 1 for i in range(num_chunks): chunks.append(df[i*chunk_size:(i+1)*chunk_size]) return chunks
źródło
Chyba teraz możemy wykorzystać zwykły
iloc
zrange
tego.chunk_size = int(df.shape[0] / 4) for start in range(0, df.shape[0], chunk_size): df_subset = df.iloc[start:start + chunk_size] process_data(df_subset) ....
źródło
Należy pamiętać, że
np.array_split(df, 3)
dzieli ramkę danych na 3 podramki danych, podczas gdysplit_dataframe
funkcja zdefiniowana w odpowiedzi @ elixir , wywoływana jakosplit_dataframe(df, chunk_size=3)
, dzieli ramkę danych w każdymchunk_size
wierszu.Przykład:
Z
np.array_split
:df = pd.DataFrame([1,2,3,4,5,6,7,8,9,10,11], columns=['TEST']) df_split = np.array_split(df, 3)
... otrzymujesz 3 pod-ramki danych:
df_split[0] # 1, 2, 3, 4 df_split[1] # 5, 6, 7, 8 df_split[2] # 9, 10, 11
Z
split_dataframe
:df_split2 = split_dataframe(df, chunk_size=3)
... otrzymujesz 4 podramki danych:
df_split2[0] # 1, 2, 3 df_split2[1] # 4, 5, 6 df_split2[2] # 7, 8, 9 df_split2[3] # 10, 11
Mam nadzieję, że mam rację i że to jest przydatne.
źródło
Uwaga:
np.array_split
nie działa z numpy-1.9.0. Sprawdziłem: działa z 1.8.1.Błąd:
źródło
Możesz użyć
groupby
, zakładając, że masz indeks wyliczeniowy w postaci całkowitej:import math df = pd.DataFrame(dict(sample=np.arange(99))) rows_per_subframe = math.ceil(len(df) / 4.) subframes = [i[1] for i in df.groupby(np.arange(len(df))//rows_per_subframe)]
Uwaga:
groupby
zwraca krotkę, w której drugim elementem jest ramka danych, stąd nieco skomplikowane wyodrębnianie.>>> len(subframes), [len(i) for i in subframes] (4, [25, 25, 25, 24])
źródło
Doświadczyłem również, że np.array_split nie działa z Pandas DataFrame, moim rozwiązaniem było tylko podzielenie indeksu DataFrame, a następnie wprowadzenie nowej kolumny z etykietą „group”:
indexes = np.array_split(df.index,N, axis=0) for i,index in enumerate(indexes): df.loc[index,'group'] = i
To sprawia, że operacje grouby są bardzo wygodne, na przykład obliczanie średniej wartości każdej grupy:
df.groupby(by='group').mean()
źródło
możesz użyć wyrażeń listowych, aby to zrobić w jednej linii
n = 4 chunks = [df[i:i+n] for i in range(0,df.shape[0],n)]
źródło