2013-07-21 33 views
6

Tôi có một DataFrame có chứa giá trị cổ phiếu.Cột mới dựa trên lựa chọn có điều kiện từ các giá trị của 2 cột khác trong một khung dữ liệu Pandas

Nó trông như thế này:

>>>Data Open High Low Close Volume Adj Close Date              
2013-07-08 76.91 77.81 76.85 77.04 5106200 77.04 

Khi tôi cố gắng tạo ra một cột mới có điều kiện như sau câu lệnh if:

Data['Test'] =Data['Close'] if Data['Close'] > Data['Open'] else Data['Open'] 

tôi nhận được lỗi sau:

Traceback (most recent call last): 
    File "<pyshell#116>", line 1, in <module> 
    Data[1]['Test'] =Data[1]['Close'] if Data[1]['Close'] > Data[1]['Open'] else Data[1]['Open'] 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

Sau đó, tôi đã sử dụng a.all():

Data[1]['Test'] =Data[1]['Close'] if all(Data[1]['Close'] > Data[1]['Open']) else Data[1]['Open'] 

Kết quả là toàn bộ cột ['Open'] được chọn. Tôi đã không nhận được điều kiện mà tôi muốn, đó là chọn mỗi lần giá trị lớn nhất giữa các cột ['Open']['Close'].

Mọi trợ giúp đều được đánh giá cao.

Cảm ơn.

Trả lời

4

Từ một DataFrame như:

>>> df 
     Date Open High Low Close Volume Adj Close 
0 2013-07-08 76.91 77.81 76.85 77.04 5106200  77.04 
1 2013-07-00 77.04 79.81 71.81 72.87 1920834  77.04 
2 2013-07-10 72.87 99.81 64.23 93.23 2934843  77.04 

Điều đơn giản nhất tôi có thể nghĩ đến sẽ là:

>>> df["Test"] = df[["Open", "Close"]].max(axis=1) 
>>> df 
     Date Open High Low Close Volume Adj Close Test 
0 2013-07-08 76.91 77.81 76.85 77.04 5106200  77.04 77.04 
1 2013-07-00 77.04 79.81 71.81 72.87 1920834  77.04 77.04 
2 2013-07-10 72.87 99.81 64.23 93.23 2934843  77.04 93.23 

df.ix[:,["Open", "Close"]].max(axis=1) có thể nhanh hơn một chút, nhưng tôi không nghĩ rằng nó là tốt đẹp để tìm kiếm tại.

Ngoài ra, bạn có thể sử dụng .apply trên các hàng:

>>> df["Test"] = df.apply(lambda row: max(row["Open"], row["Close"]), axis=1) 
>>> df 
     Date Open High Low Close Volume Adj Close Test 
0 2013-07-08 76.91 77.81 76.85 77.04 5106200  77.04 77.04 
1 2013-07-00 77.04 79.81 71.81 72.87 1920834  77.04 77.04 
2 2013-07-10 72.87 99.81 64.23 93.23 2934843  77.04 93.23 

Hoặc rơi trở lại NumPy:

>>> df["Test"] = np.maximum(df["Open"], df["Close"]) 
>>> df 
     Date Open High Low Close Volume Adj Close Test 
0 2013-07-08 76.91 77.81 76.85 77.04 5106200  77.04 77.04 
1 2013-07-00 77.04 79.81 71.81 72.87 1920834  77.04 77.04 
2 2013-07-10 72.87 99.81 64.23 93.23 2934843  77.04 93.23 

Vấn đề cơ bản là if/else không chơi độc đáo với mảng, vì if (something) luôn ép buộc something thành một đơn bool.Nó không tương đương với "cho mọi phần tử trong mảng một cái gì đó, nếu điều kiện giữ" hoặc bất cứ điều gì như thế.

0

Vấn đề là bạn đang yêu cầu python đánh giá điều kiện (Data['Close'] > Data['Open']) chứa nhiều giá trị boolean. Bạn không muốn sử dụng any hoặc all kể từ đó, vì điều đó sẽ đặt Data['Test'] thành Data['Open'] hoặc Data['Close'].

Có thể có một phương pháp sạch hơn, nhưng có một cách tiếp cận là sử dụng một mặt nạ (mảng boolean):

mask = Data['Close'] > Data['Open'] 
Data['Test'] = pandas.concat([Data['Close'][mask].dropna(), Data['Open'][~mask].dropna()]).reindex_like(Data) 
3
In [7]: df = DataFrame(randn(10,2),columns=list('AB')) 

In [8]: df 
Out[8]: 
      A   B 
0 -0.954317 -0.485977 
1 0.364845 -0.193453 
2 0.020029 -1.839100 
3 0.778569 0.706864 
4 0.033878 0.437513 
5 0.362016 0.171303 
6 2.880953 0.856434 
7 -0.109541 0.624493 
8 1.015952 0.395829 
9 -0.337494 1.843267 

Đây là một nơi có điều kiện, nói cho tôi giá trị cho A nếu A> B, nếu không cho tôi B

# this syntax is EQUIVALENT to 
# df.loc[df['A']>df['B'],'A'] = df['B'] 

In [9]: df['A'].where(df['A']>df['B'],df['B']) 
Out[9]: 
0 -0.485977 
1 0.364845 
2 0.020029 
3 0.778569 
4 0.437513 
5 0.362016 
6 2.880953 
7 0.624493 
8 1.015952 
9 1.843267 
dtype: float64 

Trong trường hợp này max tương đương

In [10]: df.max(1) 
Out[10]: 
0 -0.485977 
1 0.364845 
2 0.020029 
3 0.778569 
4 0.437513 
5 0.362016 
6 2.880953 
7 0.624493 
8 1.015952 
9 1.843267 
dtype: float64 
+0

nơi tôi có '' df ['B'] '' bạn có thể đặt một vô hướng (ví dụ 'Đóng'), mặc dù bạn thực sự nên làm điều này trong một cột khác (ví dụ cột bạn chọn từ, '' df [' A '] '' không nhất thiết phải giống như mặt nạ '' df [' A ']> df [' B '] '', nếu không bạn sẽ nhận được cột dấu phẩy/chuỗi hỗn hợp, thường không hữu ích (và không Bạn cũng có thể có một cột khác, nơi tôi có '' df ['B'] '' làm giá trị thay thế (và gấu trúc sẽ căn chỉnh nó với cột chọn) .Tuy nhiên điều này là chính xác tương đương với: '' df .loc [df ['A']> df ['B'], 'A'] = df ['B'] '' – Jeff