23

请帮助 - 我不断收到以下回溯错误:

当前运行 Python 2.0

我正在尝试利用 Python 的 Plotly 库来显示说明比特币价格的信息图。我尝试在代码顶部导入日期时间,但这似乎无法解决问题。

Traceback (most recent call last):
  File "project_one.py", line 165, in <module>
    crypto_price_df = get_crypto_data(coinpair)
  File "project_one.py", line 155, in get_crypto_data
    json_url = base_polo_url.format(poloniex_pair, start_date.timestamp(), end_date.timestamp(), pediod)
AttributeError: 'datetime.datetime' object has no attribute 'timestamp'

我的代码从这里开始

import numpy as np
import pandas as pd
from pandas import Series, DataFrame, Panel
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
import seaborn as sns
import sklearn as sk
import scipy as sp
import os
import pickle
import quandl
import datetime
import plotly.plotly as py
import plotly.graph_objs as go
import plotly.figure_factory as ff
from plotly import tools
from plotly.offline import iplot, init_notebook_mode
from IPython.display import display, HTML
init_notebook_mode(connected=True)


def get_quandl_data(quandl_id):

    cache_path = '{}.pkl'.format(quandl_id).replace('/','-')
    try:
        f = open(cache_path, 'rb')
        df = pickle.load(f)   
        print('Loaded {} from cache'.format(quandl_id))
    except (OSError, IOError) as e:
        print('Downloading {} from Quandl'.format(quandl_id))
        df = quandl.get(quandl_id, returns="pandas")
        df.to_pickle(cache_path)
        print('Cached {} at {}'.format(quandl_id, cache_path))
    return df


btc_usd_price_kraken = get_quandl_data('BCHARTS/KRAKENUSD')



exchanges = ['COINBASE','BITSTAMP','ITBIT']

exchange_data = {}

exchange_data['KRAKEN'] = btc_usd_price_kraken

for exchange in exchanges:
    exchange_code = 'BCHARTS/{}USD'.format(exchange)
    btc_exchange_df = get_quandl_data(exchange_code)
    exchange_data[exchange] = btc_exchange_df

def merge_dfs_on_column(dataframes, labels, col):

    series_dict = {}
    for index in range(len(dataframes)):
        series_dict[labels[index]] = dataframes[index][col]

    return pd.DataFrame(series_dict) 


btc_usd_datasets = merge_dfs_on_column(list(exchange_data.values()), 
list(exchange_data.keys()), 'Weighted Price')



def df_scatter(df, title, seperate_y_axis=False, y_axis_label='', 
scale='linear', initial_hide=False):

    label_arr = list(df)
    series_arr = list(map(lambda col: df[col], label_arr))

    layout = go.Layout(
        title=title,
        legend=dict(orientation="h"),
        xaxis=dict(type='date'),
        yaxis=dict(
            title=y_axis_label,
            showticklabels= not seperate_y_axis,
            type=scale
        )
    )

    y_axis_config = dict(
        overlaying='y',
        showticklabels=False,
        type=scale )

    visibility = 'visible'
    if initial_hide:
        visibility = 'legendonly'


    trace_arr = []
    for index, series in enumerate(series_arr):
        trace = go.Scatter(
            x=series.index, 
            y=series, 
            name=label_arr[index],
            visible=visibility
        )


        if seperate_y_axis:
            trace['yaxis'] = 'y{}'.format(index + 1)
            layout['yaxis{}'.format(index + 1)] = y_axis_config    
        trace_arr.append(trace)

    fig = go.Figure(data=trace_arr, layout=layout)
    py.plot(fig)



df_scatter(btc_usd_datasets, 'Bitcoin Price (USD) By Exchange')


btc_usd_datasets.replace(0, np.nan, inplace=True)


df_scatter(btc_usd_datasets, 'Bitcoin Price (USD) By Exchange')


btc_usd_datasets['avg_btc_price_usd'] = btc_usd_datasets.mean(axis=1)



btc_trace = go.Scatter(x=btc_usd_datasets.index, 
y=btc_usd_datasets['avg_btc_price_usd'])
py.plot([btc_trace])



def get_json_data(json_url, cache_path):

    try:        
        f = open(cache_path, 'rb')
        df = pickle.load(f)   
        print('Loaded {} from cache'.format(json_url))
    except (OSError, IOError) as e:
        print('Downloading {}'.format(json_url))
        df = pd.read_json(json_url)
        df.to_pickle(cache_path)
        print('Cached {} at {}'.format(json_url, cache_path))
    return df

# Helper Function that Generates Poloniex API HTTP requests
base_polo_url = 'https://poloniex.com/public? 
command=returnChartData&currencyPair={}&start={}&end={}&period={}'
start_date = datetime.datetime.strptime('2015-01-01', '%Y-%m-%d') # get 
data from the start of 2015
end_date = datetime.datetime.now() # up until today
pediod = 86400 # pull daily data (86,400 seconds per day)

def get_crypto_data(poloniex_pair):

    json_url = base_polo_url.format(poloniex_pair, start_date.timestamp(), end_date.timestamp(), pediod)
    data_df = get_json_data(json_url, poloniex_pair)
    data_df = data_df.set_index('date') 
    return data_df


altcoins = ['ETH','LTC','XRP','ETC','STR','DASH','SC','XMR','XEM']
altcoin_data = {}
for altcoin in altcoins:
    coinpair = 'BTC_{}'.format(altcoin)
    crypto_price_df = get_crypto_data(coinpair)
    altcoin_data[altcoin] = crypto_price_df
4

7 回答 7

20

timestamp方法是在 Python 3.3 中添加的。因此,如果您使用的是 Python 2.0,甚至是 2.7,您就没有它。

PyPI 上有当前datetime到旧 Python 版本的反向移植,但它们似乎都不是官方的或最新的;您可能想尝试自己搜索。

还有一些第三方替换库添加了 (2.x) 中没有的功能datetime,包括转换为 Unix 时间戳的能力。


您可以从 3.3 或更高版本的源代码中复制该函数

def timestamp(self):
    "Return POSIX timestamp as float"
    if self._tzinfo is None:
        s = self._mktime()
        return s + self.microsecond / 1e6
    else:
        return (self - _EPOCH).total_seconds()

......但你必须稍微修改一下才能让它们工作,因为:

  • _EPOCH在模块末尾删除。
  • 3.x_EPOCH是一个使用正确的 UTC 时区构建的 tz 感知对象,除非您使用像pytz.
  • _mktime方法和_tzinfo属性在 2.x 上不存在datetime,因此您还需要模拟它们的作用。

如果您不需要相同的功能同样适用于 naive、GMT 和 tz 感知的日期时间,那么它不会那么难,但它仍然不是很简单——如果您确实需要完整的功能,它会继续变得更痛苦。


或者移植文档中给出的等效代码可能更容易。

对于有意识的datetime实例:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

当然你还没有那个timezone.utc,但是为了这个目的,你不需要一个完整的时区对象;您可以使用2.x文档中的示例UTC类的实例。tzinfo

……天真:

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

… 或者:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)

由于您不知道日期时间,因此您只需要最后一个。


如果您的 Python 足够老,timedelta可能没有__div__方法。在这种情况下(如果您还没有找到反向移植),您还必须手动进行除法,方法是调用total_seconds每一个,确保其中至少一个是浮点数,然后除以数字:

timestamp = ((dt - datetime(1970, 1, 1)).total_seconds() / 
    float(timedelta(seconds=1).total_seconds()))

但在这种特殊情况下,很明显除数将是 1.0,除以 1.0 与什么都不做是一样的,所以:

timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
于 2018-06-01T20:53:28.813 回答
15

正如其他答案所述,datetime.timestamp()已在Python 3.3上添加。

要在 Python < 3.3 上获得类似的行为,您需要使用time.mktime()

import time

def to_seconds(date):
    return time.mktime(date.timetuple())

然后,而不是打电话start_date.timestamp(),你只是打电话to_seconds(start_date)

于 2018-06-01T21:02:44.670 回答
5

.timestamp()方法是在 python 版本 3.3 [ source ] 中添加的,因此您不能.timestamp()在 Python 2 中使用。

于 2018-06-01T20:48:45.913 回答
2

理解一个简单的版本独立使用将如下:

import datetime
import sys
if sys.version_info[0] < 3 or sys.version_info[1] < 4:
    # python version < 3.3
    import time
    def timestamp(date):
        return time.mktime(date.timetuple())
else:
    def timestamp(date):
        return date.timestamp()

# Example usecase:
date = datetime.datetime.strptime('2015-01-01', '%Y-%m-%d')
print(timestamp(date))
于 2019-05-03T12:12:17.670 回答
0

如果要计数到微秒/纳秒,则必须执行以下操作..

import time
from datetime import datetime

timestamp_str = '2021.01.21 11:11:52:238'
dt_obj = datetime.strptime(timestamp_str, '%Y.%m.%d %H:%M:%S:%f')
timestamp = time.mktime(dt_obj.timetuple()) + dt_obj.microsecond / 1e6
timestamp_ns = int(timestamp * 1000000000)
print(timestamp_ns)
于 2021-01-28T06:22:15.933 回答
0

在 Python 2.x 中,您只需要使用模块中的方法time()time如下所示:

>>> from time import time
>>> time()
1535495731.95094

它将为您提供与Python 3.x 对象中的方法相同的timestamp()方法:datetime

>>> from datetime import datetime
>>> datetime.now().timestamp()
1535495993.949849

但这仅在您需要当前时间戳而不是任何时间戳时才有效。

官方文档:https ://docs.python.org/2/library/time.html#time.time

于 2018-08-28T22:41:47.550 回答
0

这是一个非常简单的解决方案:在进一步移动之前,请确保您已经安装了 python 3.3 或更高版本。您可以像这样替换您的运行命令。在使用命令运行 python 脚本之前:

python <your_script_name.py>

像这样替换这个命令:

python3 <your_script_name.py>

我希望这能解决你的问题。

于 2021-01-21T17:01:26.647 回答