Tách một khung dữ liệu gấu trúc lớn


87

Tôi có một khung dữ liệu lớn với 423244 dòng. Tôi muốn chia mã này thành 4. Tôi đã thử mã sau có lỗi?ValueError: array split does not result in an equal division

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

Làm thế nào để chia khung dữ liệu này thành 4 nhóm?


Chúng tôi muốn một np.split(df, N)chức năng xin vui lòng.
Sören

Câu trả lời:


182

Sử dụng 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]

Cảm ơn rất nhiều! Ngoài ra, tôi muốn áp dụng một số chức năng cho từng nhóm? Làm thế nào để truy cập từng nhóm một?
Nilani Algiriyage

7
@NilaniAlgiriyage - array_splittrả về danh sách các DataFrame, vì vậy bạn có thể chỉ cần lặp qua danh sách ...
root

Tôi đang chia nhỏ khung dữ liệu vì nó quá lớn. Tôi muốn lấy nhóm đầu tiên và áp dụng chức năng, sau đó đến nhóm thứ hai và áp dụng chức năng, v.v. vậy làm cách nào để truy cập từng nhóm?
Nilani Algiriyage

1
Làm cách nào để bạn không nhận được AttributeError vì Dataframe không có 'kích thước'.
Boosted_d

2
Câu trả lời này là lỗi thời:AttributeError: 'DataFrame' object has no attribute 'size'
Tjorriemorrie

33

Tôi cũng muốn làm như vậy, và đầu tiên tôi gặp sự cố với chức năng phân tách, sau đó là sự cố với việc cài đặt pandas 0.15.2, vì vậy tôi quay lại phiên bản cũ và viết một hàm nhỏ hoạt động rất tốt. Tôi hy vọng điều này có thể giúp ích!

# 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
nhanh hơn nhiều so với sử dụng np.array_split ()
jgaw

4
Cách chính xác để tính sốChunks nhập số toán họcChunks = math.ceil (len (df) / chunkSize)
Sergey Leyko

21

Tôi đoán bây giờ chúng ta có thể sử dụng đơn giản ilocvới rangecho việc này.

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
Đơn giản và trực quan
rmstmppr

14

Hãy lưu ý rằng np.array_split(df, 3)phân chia khung dữ liệu thành 3 khung dữ liệu phụ, trong khi split_dataframehàm được xác định trong câu trả lời của @ elixir , khi được gọi là split_dataframe(df, chunk_size=3), sẽ chia khung dữ liệu mỗi chunk_sizehàng.

Thí dụ:

Với 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)

... bạn nhận được 3 khung dữ liệu phụ:

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

Với split_dataframe:

df_split2 = split_dataframe(df, chunk_size=3)

... bạn nhận được 4 khung dữ liệu phụ:

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

Hy vọng tôi đúng, và điều này hữu ích.


có cách nào dễ dàng để làm cho quá trình này trở nên ngẫu nhiên. Tôi chỉ có thể nghĩ đến việc thêm một cột rondom, tách và loại bỏ các cột ngẫu nhiên nhưng có thể có một cách dễ dàng hơn
Rutger Hofste

chúng có phải có kích thước đoạn bằng nhau không?
InquilineKea

8

Thận trọng:

np.array_splitkhông hoạt động với numpy-1.9.0. Tôi đã kiểm tra: Nó hoạt động với 1.8.1.

Lỗi:

Khung dữ liệu không có thuộc tính 'kích thước'


6
tôi đã gửi một lỗi trong github của gấu trúc: github.com/pydata/pandas/issues/8846 có vẻ như nó đã được sửa cho gấu trúc 0.15.2
yemu

4

Bạn có thể sử dụng groupby, giả sử bạn có một chỉ mục được liệt kê số nguyên:

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

Lưu ý: groupbytrả về một bộ giá trị trong đó phần tử thứ 2 là khung dữ liệu, do đó việc trích xuất hơi phức tạp.

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

1

Tôi cũng gặp phải trường hợp np.array_split không làm việc với Pandas DataFrame, giải pháp của tôi là chỉ tách chỉ mục của DataFrame và sau đó giới thiệu một cột mới có nhãn "nhóm":

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

Điều này làm cho các phép toán cá mú trở nên rất thuận tiện để tính toán ví dụ về giá trị trung bình của mỗi nhóm:

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

0

bạn có thể sử dụng khả năng hiểu danh sách để làm điều này trong một dòng

n = 4
chunks = [df[i:i+n] for i in range(0,df.shape[0],n)]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.