Büyük bir panda veri çerçevesini bölme


92

423244 satırlık büyük bir veri çerçevem ​​var. Bunu 4'e bölmek istiyorum. Hata veren aşağıdaki kodu denedim?ValueError: array split does not result in an equal division

for item in np.split(df, 4):
    print item

Bu veri çerçevesi 4 gruba nasıl bölünür?


Bir np.split(df, N)işlev istiyoruz lütfen.
Sören

Yanıtlar:


193

Kullanım 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]

8
@NilaniAlgiriyage - DataFrame'lerin array_splitbir listesini döndürür, böylece listeye göz atabilirsiniz ...
root

1
Dataframe 'boyutu' olmadığı için AttributeError hatası nasıl elde edilmez?
Boosted_d16

2
Bu cevap güncel değil:AttributeError: 'DataFrame' object has no attribute 'size'
Tjorriemorrie

1
Cevap harika çalışıyor! Yoğun hesaplamalar yaparken veri çerçevesi yığınlarının üzerinden
geçmek

1
Şaşırtıcı derecede basit! Teşekkürler
Viv

36

Ben de aynısını yapmak istedim ve önce split işleviyle ilgili sorunlar yaşadım, sonra pandalar 0.15.2'yi kurarken sorunlar yaşadım, bu yüzden eski sürümüme döndüm ve çok iyi çalışan küçük bir işlev yazdım. Umarım bu yardımcı olabilir!

# 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

5
np.array_split () kullanmaktan çok daha hızlı
jgaw

5
Sayı hesaplamanın doğru yoluChunks içe aktar matematik numarasıChunks = math.ceil (len (df) / chunkSize)
Sergey

21

Şimdi biz düz kullanabilirsiniz tahmin ilocile rangebunun için.

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)
    ....

1
Basit ve sezgisel
rmstmppr

15

Unutmayın np.array_split(df, 3)ederken, 3 alt dataframes içine dataframe böler split_dataframefonksiyonu tanımlanan @ iksir cevabı olarak adlandırılan zaman, split_dataframe(df, chunk_size=3)her dataframe böler chunk_sizesatırlar.

Misal:

İle 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)

... 3 alt veri çerçevesi elde edersiniz:

df_split[0] # 1, 2, 3, 4
df_split[1] # 5, 6, 7, 8
df_split[2] # 9, 10, 11

İle split_dataframe:

df_split2 = split_dataframe(df, chunk_size=3)

... 4 alt veri çerçevesi elde edersiniz:

df_split2[0] # 1, 2, 3
df_split2[1] # 4, 5, 6
df_split2[2] # 7, 8, 9
df_split2[3] # 10, 11

Umarım haklıyımdır ve bu yararlıdır.


bu işlemi rastgele yapmanın kolay bir yolu var mı? Sadece bir rondom sütunu eklemeyi, rastgele sütunu bölmeyi ve kaldırmayı düşünebilirim ama daha kolay bir yol olabilir
Rutger Hofste

eşit büyüklükte olmak zorunda mı?
InquilineKea


4

groupbyBir tamsayı numaralandırılmış dizininiz olduğunu varsayarak kullanabilirsiniz :

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)]

Not: groupby2. elemanın veri çerçevesi olduğu bir demet döndürür, dolayısıyla biraz karmaşık çıkarım olur.

>>> len(subframes), [len(i) for i in subframes]
(4, [25, 25, 25, 24])

1

Ayrıca np.array_split'in Pandas DataFrame ile çalışmadığını da deneyimledim, çözümüm yalnızca DataFrame dizinini bölmek ve ardından "grup" etiketli yeni bir sütun sunmaktı:

indexes = np.array_split(df.index,N, axis=0)
for i,index in enumerate(indexes):
   df.loc[index,'group'] = i

Bu, gruplama işlemlerini, örneğin her grubun ortalama değerinin hesaplanması için çok uygun hale getirir:

df.groupby(by='group').mean()

1

bunu tek bir satırda yapmak için liste anlamalarını kullanabilirsiniz

n = 4
chunks = [df[i:i+n] for i in range(0,df.shape[0],n)]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.