Cách lấy các lát dữ liệu cột trong gấu trúc


264

Tôi tải một số dữ liệu học máy từ tệp CSV. 2 cột đầu tiên là các quan sát và các cột còn lại là các tính năng.

Hiện tại, tôi làm như sau:

data = pandas.read_csv('mydata.csv')

cung cấp một cái gì đó như:

data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))

Tôi muốn cắt dataframe này trong hai dataframes: một chứa các cột abvà một chứa các cột c, de.

Không thể viết một cái gì đó như

observations = data[:'c']
features = data['c':]

Tôi không chắc phương pháp tốt nhất là gì. Tôi có cần pd.Panelkhông?

Nhân tiện, tôi thấy việc lập chỉ mục khung dữ liệu khá không nhất quán: data['a']được phép, nhưng data[0]không được. Mặt khác, data['a':]không được phép nhưng data[0:]là. Có một lý do thực tế cho việc này? Điều này thực sự khó hiểu nếu các cột được lập chỉ mục bởi Int, cho rằngdata[0] != data[0:1]


3
DataFrame vốn dĩ là một đối tượng giống như dict khi bạn thực hiện df [...], tuy nhiên một số tiện ích, ví dụ: df[5:10]đã được thêm vào để chọn hàng ( pandas.pydata.org/pandas-docs/ sóng / trộm )
Wes McKinney

1
Vì vậy, sự không nhất quán này là một quyết định thiết kế có lợi cho sự thuận tiện? Được rồi, nhưng nó chắc chắn cần phải rõ ràng hơn cho người mới bắt đầu!
cpa

3
Việc xem xét thiết kế hỗ trợ thuận tiện làm cho đường cong học tập dốc hơn nhiều. Tôi muốn rằng có tài liệu tốt hơn cho sự khởi đầu chỉ cần trình bày một giao diện nhất quán. Ví dụ, chỉ tập trung vào giao diện ix.
Yu Shen

Câu trả lời:


243

Trả lời 2017 - gấu trúc 0,20: .ix không được dùng nữa. Sử dụng .loc

Xem sự phản đối trong các tài liệu

.locsử dụng lập chỉ mục dựa trên nhãn để chọn cả hàng và cột. Các nhãn là các giá trị của chỉ mục hoặc các cột. Cắt lát .locbao gồm các yếu tố cuối cùng.

Giả sử chúng ta có một DataFrame với các cột sau:
foo, bar, quz, ant, cat, sat, dat.

# selects all rows and all columns beginning at 'foo' up to and including 'sat'
df.loc[:, 'foo':'sat']
# foo bar quz ant cat sat

.locchấp nhận cùng một ký hiệu lát mà danh sách Python thực hiện cho cả hàng và cột. Ký hiệu látstart:stop:step

# slice from 'foo' to 'cat' by every 2nd column
df.loc[:, 'foo':'cat':2]
# foo quz cat

# slice from the beginning to 'bar'
df.loc[:, :'bar']
# foo bar

# slice from 'quz' to the end by 3
df.loc[:, 'quz'::3]
# quz sat

# attempt from 'sat' to 'bar'
df.loc[:, 'sat':'bar']
# no columns returned

# slice from 'sat' to 'bar'
df.loc[:, 'sat':'bar':-1]
sat cat ant quz bar

# slice notation is syntatic sugar for the slice function
# slice from 'quz' to the end by 2 with slice function
df.loc[:, slice('quz',None, 2)]
# quz cat dat

# select specific columns with a list
# select columns foo, bar and dat
df.loc[:, ['foo','bar','dat']]
# foo bar dat

Bạn có thể cắt theo hàng và cột. Ví dụ, nếu bạn có 5 hàng với nhãn v, w, x, y,z

# slice from 'w' to 'y' and 'foo' to 'ant' by 3
df.loc['w':'y', 'foo':'ant':3]
#    foo ant
# w
# x
# y

nếu việc sử dụng của bạn áp dụng với hàng lambda, như trong: df['newcol'] = df.apply(lambda row: myfunc(row), axis=1) thì bạn có thể myfunc(row){... sử dụng row['foo':'ant']. ví dụ (theo câu trả lời StackOverflow này ), bên trong myfuncbạn có thể đánh giá nếu bất kỳ thứ nào trong số này không phải là số:row['foo':'ant'].apply(lambda x: isinstance(x, str)).any()
pashute

4
.ilocnên được sử dụng ngay bây giờ, thay vì .loc. Khắc phục điều đó và tôi sẽ nâng cấp nó.
vươn

1
@craned - điều đó không đúng. Từ tài liệu Pandas: .loc chủ yếu dựa trên nhãn, nhưng cũng có thể được sử dụng với một mảng boolean. .loc sẽ tăng KeyError khi không tìm thấy các mục. Một tuyên bố tương tự được thực hiện về .iloc ngoại trừ nó đặc biệt đề cập đến việc cắt chỉ mục. Nói cách khác trong ví dụ này, ông đã sử dụng lập chỉ mục dựa trên nhãn và .loc là lựa chọn chính xác (về cơ bản là lựa chọn duy nhất). Nếu bạn muốn cắt theo vị trí-ví dụ 5:10, thì hãy sử dụng .iloc
user2103050

149

Lưu ý: .ix đã bị từ chối kể từ Pandas v0.20. Thay vào đó, bạn nên sử dụng .lochoặc .iloc, khi thích hợp.

Chỉ mục DataFrame.ix là những gì bạn muốn truy cập. Có một chút khó hiểu (tôi đồng ý rằng lập chỉ mục Pandas đôi khi rất khó hiểu!), Nhưng những điều sau đây dường như làm những gì bạn muốn:

>>> df = DataFrame(np.random.rand(4,5), columns = list('abcde'))
>>> df.ix[:,'b':]
      b         c         d         e
0  0.418762  0.042369  0.869203  0.972314
1  0.991058  0.510228  0.594784  0.534366
2  0.407472  0.259811  0.396664  0.894202
3  0.726168  0.139531  0.324932  0.906575

trong đó .ix [lát hàng, lát cột] là những gì đang được diễn giải. Thông tin thêm về lập chỉ mục Pandas tại đây: http://pandas.pydata.org/pandas-docs/urdy/indexing.html#indexing-advified


5
Cẩn thận rằng phạm vi trong gấu trúc bao gồm cả hai điểm cuối, tức là>>>data.ix[:, 'a':'c'] a b c 0 0.859192 0.881433 0.843624 1 0.744979 0.427986 0.177159
châu chấu

21
Nhiều cột taxi được thông qua như thế nàydf.ix[:,[0,3,4]]
user602599

3
@Karmel: Có vẻ như lỗi sao chép / dán ở đầu ra ở trên. Có lẽ bạn có ý nghĩa df.ix[:,'b':'e']?
ChaimG

6
Tốt hơn là sử dụng locthay vì ix: stackoverflow.com/a/31593712/4323
John Zwinck

5
Câu trả lời cũ như thế này cần phải được xóa. .ix không dùng nữa và không bao giờ được sử dụng.
Ted Petrou

75

Hãy sử dụng bộ dữ liệu titanic từ gói seaborn làm ví dụ

# Load dataset (pip install seaborn)
>> import seaborn.apionly as sns
>> titanic = sns.load_dataset('titanic')

sử dụng tên cột

>> titanic.loc[:,['sex','age','fare']]

sử dụng các chỉ số cột

>> titanic.iloc[:,[2,3,6]]

sử dụng ix (Cũ hơn Pandas <.20 phiên bản)

>> titanic.ix[:,[‘sex’,’age’,’fare’]]

hoặc là

>> titanic.ix[:,[2,3,6]]

sử dụng phương pháp reindex

>> titanic.reindex(columns=['sex','age','fare'])

6
Trong gấu trúc 0,20: .ixbị phản đối.
Shihe Zhang

cảnh báo không dùng nữa: Passing list-likes to .loc or [] with any missing label will raise KeyError in the future, you can use .reindex() as an alternative.khi bạn sử dụngdf.loc[:, some_list_of_columns]
Marc Maxmeister

35

Ngoài ra, đưa ra một DataFrame

dữ liệu

như trong ví dụ của bạn, nếu bạn chỉ muốn trích xuất cột a và d (ei cột thứ 1 và thứ 4), iloc mothod từ dataframe là những gì bạn cần và có thể được sử dụng rất hiệu quả. Tất cả những gì bạn cần biết là chỉ mục của các cột bạn muốn trích xuất. Ví dụ:

>>> data.iloc[:,[0,3]]

sẽ cho bạn

          a         d
0  0.883283  0.100975
1  0.614313  0.221731
2  0.438963  0.224361
3  0.466078  0.703347
4  0.955285  0.114033
5  0.268443  0.416996
6  0.613241  0.327548
7  0.370784  0.359159
8  0.692708  0.659410
9  0.806624  0.875476

25

Bạn có thể cắt dọc theo các cột của a DataFramebằng cách tham khảo tên của từng cột trong danh sách, như vậy:

data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))
data_ab = data[list('ab')]
data_cde = data[list('cde')]

Vì vậy, nếu tôi muốn tất cả dữ liệu bắt đầu từ cột 'b', tôi cần tìm chỉ mục của 'b' trong data.columns và thực hiện dữ liệu [data.columns [1:]]? Đó là cách hoạt động kinh điển?
cpa

1
Bạn có nghĩa là bạn muốn chọn tất cả các cột từ 'b' trở đi?
Gỗ Brendan

Có, hoặc chọn tất cả các cột trong một phạm vi nhất định.
cpa

Bản thân tôi khá mới mẻ với gấu trúc, vì vậy tôi không thể nói như những gì được coi là kinh điển. Tôi sẽ làm như bạn đã nói, nhưng sử dụng get_lochàm trên data.columnsđể xác định chỉ số của cột 'b' hoặc bất cứ điều gì.
Gỗ Brendan

20

Và nếu bạn đến đây để tìm cách cắt hai dãy cột và kết hợp chúng lại với nhau (như tôi), bạn có thể làm một cái gì đó như

op = df[list(df.columns[0:899]) + list(df.columns[3593:])]
print op

Điều này sẽ tạo ra một khung dữ liệu mới với 900 cột đầu tiên và (tất cả) cột> 3593 (giả sử bạn có khoảng 4000 cột trong tập dữ liệu của mình).


Tuyệt vời, ai đó đã thử điều này ... Tôi đã tự hỏi, 0: 899 này có 900 cột đầu tiên .. tại sao họ lại làm như vậy? Điều này không giống như Python chút nào. Khi sử dụng phạm vi trong python, nó luôn luôn là 'cho đến khi' không 'cho đến khi và bao gồm'
zwep

14

Dưới đây là cách bạn có thể sử dụng các phương pháp khác nhau để thực hiện cắt cột chọn lọc, bao gồm dựa trên nhãn chọn lọc, dựa trên chỉ mục và phạm vi cắt cột dựa trên phạm vi chọn lọc.

In [37]: import pandas as pd    
In [38]: import numpy as np
In [43]: df = pd.DataFrame(np.random.rand(4,7), columns = list('abcdefg'))

In [44]: df
Out[44]: 
          a         b         c         d         e         f         g
0  0.409038  0.745497  0.890767  0.945890  0.014655  0.458070  0.786633
1  0.570642  0.181552  0.794599  0.036340  0.907011  0.655237  0.735268
2  0.568440  0.501638  0.186635  0.441445  0.703312  0.187447  0.604305
3  0.679125  0.642817  0.697628  0.391686  0.698381  0.936899  0.101806

In [45]: df.loc[:, ["a", "b", "c"]] ## label based selective column slicing 
Out[45]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [46]: df.loc[:, "a":"c"] ## label based column ranges slicing 
Out[46]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [47]: df.iloc[:, 0:3] ## index based column ranges slicing 
Out[47]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

### with 2 different column ranges, index based slicing: 
In [49]: df[df.columns[0:1].tolist() + df.columns[1:3].tolist()]
Out[49]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

Hãy cố gắng tránh việc chỉ bán mã như một câu trả lời và cố gắng giải thích nó làm gì và tại sao. Mã của bạn có thể không rõ ràng đối với những người không có kinh nghiệm mã hóa có liên quan. Vui lòng chỉnh sửa câu trả lời của bạn để bao gồm làm rõ, bối cảnh và cố gắng đề cập đến bất kỳ giới hạn, giả định hoặc đơn giản hóa trong câu trả lời của bạn.
Sᴀᴍ Onᴇᴌᴀ

1

Tương đương của nó

 >>> print(df2.loc[140:160,['Relevance','Title']])
 >>> print(df2.ix[140:160,[3,7]])

1

nếu khung dữ liệu trông như thế:

group         name      count
fruit         apple     90
fruit         banana    150
fruit         orange    130
vegetable     broccoli  80
vegetable     kale      70
vegetable     lettuce   125

và OUTPUT có thể giống như

   group    name  count
0  fruit   apple     90
1  fruit  banana    150
2  fruit  orange    130

nếu bạn sử dụng toán tử logic np.logical_not

df[np.logical_not(df['group'] == 'vegetable')]

thêm về

https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html

toán tử logic khác

  1. logic_and (x1, x2, / [, out, where, ...]) Tính giá trị thật của phần tử x1 VÀ x2-khôn ngoan.

  2. logic_or (x1, x2, / [, out, where, casting, ...]) Tính giá trị thật của x1 OR x2 phần tử khôn ngoan.

  3. logic_not (x, / [, out, where, casting, ...]) Tính giá trị thật của KHÔNG x phần tử khôn ngoan.
  4. logic_xor (x1, x2, / [, out, where, ..]) Tính giá trị thật của x1 XOR x2, phần tử khôn ngoan.

0

Một cách khác để có một tập hợp các cột từ DataFrame của bạn, giả sử bạn muốn tất cả các hàng, sẽ là:
data[['a','b']]data[['c','d','e']]
nếu bạn muốn sử dụng các chỉ mục cột số, bạn có thể làm:
data[data.columns[:2]]data[data.columns[2:]]

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.