在Python中将列从对象转换为浮点时出错

时间:2019-07-14 11:52:06

标签: python pandas

使用熊猫从比特币的雅虎获得数据后,我尝试创建一种简单的交易策略:我想在收盘价为>最近50天的均值时买入,在该表达式为假时卖出。

为了模拟这一点,我创建了不同的列:

a)MA50列:显示最近50次关闭的平均值。

b)列信号:收盘>均值时显示1。否则为0。

c)列Close1:显示明天的结束时间(用于计算每日损益)

d)利润栏:显示该策略产生的每日利润/亏损。

为了计算Profit列,我简单地减去Close1 –当Signal值等于1时关闭。如果表达式为false,Profit为0。 如您所见,所有值都是数字,但是当我获得利润的结果时,我看到它是作为对象而不是数字创建的。

由于我需要将Profit列作为数值,因此我尝试使用此功能pd.to_numeric()来转换该列,但不幸的是它没有用。我还尝试使用df['Profit'] = df['Profit'].astype(float)转换Profit列。但这也不起作用。

在下面,您可以看到我正在使用的完整代码,并指出产生错误的位置:

import pandas as pd
import pandas_datareader as dr
from datetime import date

# Create DataFrame and create the Moving Average (mean) of last 50 closes
fb = dr.data.get_data_yahoo('btc-usd',start='23-01-2017',end=date.today())
fb['MA50'] = fb['Close'].rolling(50).mean()
pd.set_option('display.max_rows', 5400)

# Add a new column "Signal". When the close > MA50 Signal is 1 if not Singal is 0.
fb['Signal'] = [1 if (fb.loc[ei, 'Close']>fb.loc[ei, 'MA50']).all() else 0 for ei in fb.index]

#Add a new column "Profit", for any rows, if Signal=1, the profit is calculated as the close price of tomorrow - the close price of today. If not the profit is 0.
fb['Close1'] = fb['Close'].shift(-1)
fb['Profit'] = [(fb.loc[ei, 'Close1'] - fb.loc[ei, 'Close']) if (fb.loc[ei, 'Signal']==1).all() else 0 for ei in fb.index] #---> The error is produced in this line of code for this formula: (fb.loc[ei, 'Close1'] - fb.loc[ei, 'Close']). 

由于未知原因,如果我执行fb.info(),我会看到Profit列的值已创建为对象而不是float64

我还可以看到,在某些行中,Profit的结果不是数字。 (请参阅附件)。

Screenshot

我的目标是使用fb['Profit'].plot()在图表中绘制“利润”列。问题是,Profit列不是数字,因此,当我尝试使用它时,会收到下一条消息:

TypeError: Empty 'DataFrame': no numeric data to plot

我对长字母致歉。我曾尝试将其缩短,但我无法正确解释自己。任何帮助都将受到欢迎。谢谢!

1 个答案:

答案 0 :(得分:0)

您将列表放入X,其中包含数字和字符串。无法将其转换为数字。

例如,如您在上面的注释中所述,例如,如果X大于Open,则X为Close值,否则为0,然后执行以下操作:

df['X'] = df.Close.where(df.Close > df.Open, 0)


根据您的新解释进行更新:

import numpy as np
# Add a new column "Signal". When the close > MA50 Signal is 1 if not Singal is 0.
fb['Signal'] = np.where(fb.Close > fb.MA50, 1, 0)

#Add a new column "Profit", for any rows, if Signal=1, the profit is calculated as the close price of tomorrow - the close price of today. If not the profit is 0.
fb['Close1'] = fb['Close'].shift(-1)
fb['Profit'] = np.where(fb.Signal == 1, fb.Close1 - fb.Close, 0)

不要使用列表理解结构,它们是错误的,并引入了无法转换为数字的文本数据。