แบ่งดาต้าเฟรมแพนด้าขนาดใหญ่


92

ฉันมีดาต้าเฟรมขนาดใหญ่ที่มีเส้น 423244 ฉันต้องการแบ่งเป็น 4 ฉันลองรหัสต่อไปนี้ซึ่งทำให้เกิดข้อผิดพลาด?ValueError: array split does not result in an equal division

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

จะแบ่ง dataframe นี้เป็น 4 กลุ่มได้อย่างไร


เราต้องการnp.split(df, N)ฟังก์ชั่นโปรด
Sören

คำตอบ:


193

ใช้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 - array_splitส่งคืนรายการ DataFrames เพื่อให้คุณสามารถวนรอบรายการ ...
รูท

1
คุณจะไม่ได้รับ AttributeError ได้อย่างไรเนื่องจาก Dataframe ไม่มี 'ขนาด'
Boosted_d16

2
คำตอบนี้ล้าสมัย:AttributeError: 'DataFrame' object has no attribute 'size'
Tjorriemorrie

1
คำตอบใช้งานได้ดี! แน่นและกระชับมาก (เช่น Pythonic) สำหรับการวนซ้ำในส่วนของเฟรมข้อมูลเมื่อทำการคำนวณอย่างหนัก
openwonk

1
เรียบง่ายอย่างน่าอัศจรรย์! ขอบคุณ
Viv

36

ฉันต้องการทำเช่นเดียวกันและฉันมีปัญหาครั้งแรกกับฟังก์ชันแยกจากนั้นปัญหาในการติดตั้งแพนด้า 0.15.2 ฉันจึงกลับไปใช้เวอร์ชันเก่าและเขียนฟังก์ชันเล็กน้อยที่ใช้งานได้ดี ฉันหวังว่านี่จะช่วยได้!

# 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 () มาก
jgaw

5
วิธีที่ถูกต้องในการคำนวณ numberChunks นำเข้าหมายเลขคณิตศาสตร์Chunks = math.ceil (len (df) / chunkSize)
Sergey Leyko

21

ฉันเดาว่าตอนนี้เราสามารถใช้แบบธรรมดาilocกับrangeสิ่งนี้ได้

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
เรียบง่ายและใช้งานง่าย
rmstmppr

15

โปรดทราบว่าการnp.array_split(df, 3)แบ่ง dataframe ออกเป็น 3 sub-dataframes ในขณะที่split_dataframeฟังก์ชันที่กำหนดไว้ในคำตอบของ @ elixirเมื่อเรียกว่า as จะsplit_dataframe(df, chunk_size=3)แยกดาต้าเฟรมทุกchunk_sizeแถว

ตัวอย่าง:

ด้วย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 เฟรมข้อมูลย่อย:

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

ด้วยsplit_dataframe:

df_split2 = split_dataframe(df, chunk_size=3)

... คุณจะได้รับ 4 เฟรมข้อมูลย่อย:

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

หวังว่าฉันพูดถูกและนี่เป็นประโยชน์


มีวิธีง่ายๆในการทำให้กระบวนการนี้เป็นแบบสุ่ม ฉันคิดได้แค่การเพิ่มคอลัมน์ rondom แยกและลบคอลัมน์แบบสุ่ม แต่อาจมีวิธีที่ง่ายกว่านี้
Rutger Hofste

ต้องมีขนาดเท่ากันไหม
InquilineKea

8

ข้อควรระวัง:

np.array_splitไม่ทำงานกับ numpy-1.9.0 ฉันเช็คเอาท์: ใช้ได้กับ 1.8.1

ข้อผิดพลาด:

Dataframe ไม่มีแอตทริบิวต์ "size"


7
ฉันยื่นข้อผิดพลาดใน github แพนด้า: github.com/pydata/pandas/issues/8846 ดูเหมือนว่าจะได้รับการแก้ไขแล้วสำหรับแพนด้า 0.15.2
เยมุ

4

คุณสามารถใช้ได้โดยgroupbyสมมติว่าคุณมีดัชนีที่แจกแจงจำนวนเต็ม:

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

หมายเหตุ: groupbyส่งคืนทูเพิลซึ่งองค์ประกอบที่ 2 คือดาต้าเฟรมดังนั้นการแยกที่ซับซ้อนเล็กน้อย

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

1

ฉันยังพบว่า np.array_split ไม่ทำงานกับ Pandas DataFrame วิธีการแก้ปัญหาของฉันคือแยกเฉพาะดัชนีของ DataFrame จากนั้นแนะนำคอลัมน์ใหม่ที่มีป้ายกำกับ "group":

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

ทำให้การดำเนินการ grouby สะดวกมากสำหรับการคำนวณค่าเฉลี่ยของแต่ละกลุ่ม:

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

1

คุณสามารถใช้ความเข้าใจในรายการเพื่อทำสิ่งนี้ในบรรทัดเดียว

n = 4
chunks = [df[i:i+n] for i in range(0,df.shape[0],n)]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.