【问题标题】:Python Loop with auto creation of data frames具有自动创建数据框的 Python 循环
【发布时间】:2018-01-10 12:35:43
【问题描述】:

我正在尝试创建一个循环,该循环将为每个代码返回, 1. 不同的数据框(按股票代码的名称) 2.将时间列转换为“正常”日期 3. 它(新时间)将用作该数据帧的索引。

如果我为每个代码运行它,它就可以正常工作。 感谢您的帮助!

import requests
import pandas as pd
desired_width = 320
pd.set_option('display.width', desired_width)

data = pd.DataFrame()
tickers = ['BTC', 'ETH', 'XRP']  # pools of tickers to get
for t in tickers:  # a loop to get data ticker by ticker
        url = 'https://min-api.cryptocompare.com/data/histoday' + \
              '?fsym=' + \
                t +\
              '&tsym=USD' + \
              '&limit=600000000000' + \
              '&aggregate=1' + \
              '&e=CCCAGG'
        response = requests.get(url)
        data[t] = response.json()['Data']
        #the following 2 lines I failed to execute
        #data[t]['time'] = pd.to_datetime(data[t]['time'], unit='s')
        #data[t].index = data[t]['time']
        print("downloading data for: " + t)
        print("data for:" + t, data.head(5))

我的结果是所有三个代码的一个数据框:

数据:XRP BTC
ETH XRP 0 {'时间': 1342742400,“关闭”:8.52,“高”:8 .... {“时间”:1342742400, 'close': 0, 'high': 0, 'l... {'time': 1342742400, 'close': 0, 'high': 0, 'l... 1 {'time': 1342828800, 'close': 8.85, 'high': 9.... {'time': 1342828800, 'close': 0, 'high': 0, 'l... {'time': 1342828800,'关闭':0,'高':0,'l ... 2 {'时间':1342915200, 'close': 8.41, 'high': 8.... {'time': 1342915200, 'close': 0, 'high': 0, 'l... {'time': 1342915200, 'close': 0, 'high': 0, 'l... 3 {'time': 1343001600, 'close': 8.45, 'high': 9.... {'time': 1343001600,'关闭':0,'高':0,'l ... {'时间':1343001600, 'close': 0, 'high': 0, 'l... 4 {'time': 1343088000, 'close': 8.6, 'high': 8.8... {'time': 1343088000, 'close': 0, 'high': 0, 'l... {'time': 1343088000, 'close': 0, 'high': 0, 'l...

我在 Windows 10 上使用带有 pycharm + anconda 的 python 3.6

【问题讨论】:

    标签: python pandas python-requests


    【解决方案1】:

    我认为您可以将json_normalize 用于dinctionary of DataFrames 和concat 用于DataFrameMultiIndex - 第一级是tickers

    from pandas.io.json import json_normalize
    
    data = {}
    tickers = ['BTC', 'ETH', 'XRP']  # pools of tickers to get
    for t in tickers:  # a loop to get data ticker by ticker
            url = 'https://min-api.cryptocompare.com/data/histoday' + \
                  '?fsym=' + \
                    t +\
                  '&tsym=USD' + \
                  '&limit=600000000000' + \
                  '&aggregate=1' + \
                  '&e=CCCAGG'
            response = requests.get(url)
            data[t] = json_normalize(response.json()['Data'])
    
    df = pd.concat(data)
    print (df.head())
    
           close  high   low  open        time  volumefrom    volumeto
    BTC 0   8.52  8.87  7.60  8.87  1342742400   154661.12  1267523.74
        1   8.85  9.70  7.96  8.52  1342828800   139906.90  1242153.88
        2   8.41  8.97  8.27  8.85  1342915200    30070.67   259113.81
        3   8.45  9.20  7.75  8.41  1343001600   146396.18  1238579.49
        4   8.60  8.85  8.34  8.45  1343088000    40946.86   353506.54
    

    然后对于选择每个级别都可以使用:

    print (df.xs('BTC').head())
    
    #print (df.loc['BTC'].head())
    
       close  high   low  open        time  volumefrom    volumeto
    0   8.52  8.87  7.60  8.87  1342742400   154661.12  1267523.74
    1   8.85  9.70  7.96  8.52  1342828800   139906.90  1242153.88
    2   8.41  8.97  8.27  8.85  1342915200    30070.67   259113.81
    3   8.45  9.20  7.75  8.41  1343001600   146396.18  1238579.49
    4   8.60  8.85  8.34  8.45  1343088000    40946.86   353506.54
    

    另一种方法不是concat,只创建dictionary

    data = {}
    tickers = ['BTC', 'ETH', 'XRP']  # pools of tickers to get
    for t in tickers:  # a loop to get data ticker by ticker
            url = 'https://min-api.cryptocompare.com/data/histoday' + \
                  '?fsym=' + \
                    t +\
                  '&tsym=USD' + \
                  '&limit=600000000000' + \
                  '&aggregate=1' + \
                  '&e=CCCAGG'
            response = requests.get(url)
            data[t] = json_normalize(response.json()['Data'])
            data[t] = data[t].set_index(pd.to_datetime(data[t]['time'], unit='s'))
    
    print (data['BTC'].head())
    
                close  high   low  open        time  volumefrom    volumeto
    time                                                                   
    2012-07-20   8.52  8.87  7.60  8.87  1342742400   154661.12  1267523.74
    2012-07-21   8.85  9.70  7.96  8.52  1342828800   139906.90  1242153.88
    2012-07-22   8.41  8.97  8.27  8.85  1342915200    30070.67   259113.81
    2012-07-23   8.45  9.20  7.75  8.41  1343001600   146396.18  1238579.49
    2012-07-24   8.60  8.85  8.34  8.45  1343088000    40946.86   353506.54
    

    编辑:如果想要全局变量不推荐解决方案:

    data = {}
    tickers = ['BTC', 'ETH', 'XRP']  # pools of tickers to get
    for t in tickers:  # a loop to get data ticker by ticker
            url = 'https://min-api.cryptocompare.com/data/histoday' + \
                  '?fsym=' + \
                    t +\
                  '&tsym=USD' + \
                  '&limit=600000000000' + \
                  '&aggregate=1' + \
                  '&e=CCCAGG'
            response = requests.get(url)
            globals()['df_' + str(t)] = json_normalize(response.json()['Data'])
            globals()['df_' + str(t)] = globals()['df_' + str(t)].set_index(pd.to_datetime(globals()['df_' + str(t)]['time'], unit='s'))
    
    print (df_BTC.head())
    
                close  high   low  open        time  volumefrom    volumeto
    time                                                                   
    2012-07-20   8.52  8.87  7.60  8.87  1342742400   154661.12  1267523.74
    2012-07-21   8.85  9.70  7.96  8.52  1342828800   139906.90  1242153.88
    2012-07-22   8.41  8.97  8.27  8.85  1342915200    30070.67   259113.81
    2012-07-23   8.45  9.20  7.75  8.41  1343001600   146396.18  1238579.49
    2012-07-24   8.60  8.85  8.34  8.45  1343088000    40946.86   353506.54
    

    【讨论】:

    • 谢谢!它确实解决了问题 2 + 3,但不是第一个,它创建了 3 或 99 个不同的数据帧,每个数据帧都带有“df_”+ t,所以我将拥有 df_BTC、df_ETH 等。
    • @Giladbi - 可以使用dictionary of DataFrames 吗?
    • 但是如果真的需要,那就用globals()['df_' + str(t)] = json_normalize(response.json()['Data'])代替data[t] = json_normalize(response.json()['Data']),然后得到print (df_BTC),不过有点不合Python。
    • @Giladbi ...不建议在全局环境中存储许多类似的结构对象,如 dfs,因为它需要太多的维护和资源指针。使用 one 容器,如列表或字典,您可以通过唯一键引用每个容器,如 jezrael 所示。同样的建议也适用于 R 和其他语言!
    • @jezrael 谢谢,它可以工作,但我仍然没有解决时间格式和时间作为索引。它应该在创建不同的数据框之前完成。我试过这个:response.json()['time'] = pd.to_datetime(data[t]['time'], unit='s') 用于时间格式更改,但我搞砸了。
    【解决方案2】:

    我设法定义了一个函数来获取数据,然后使用循环来获取所有代码的数据。这样就解决了问题。

    import requests
    import datetime
    import pandas as pd
    import matplotlib.pyplot as plt
    desired_width = 320
    pd.set_option('display.width', desired_width)
    
    #function to download the Historical HOUR data
    def hourly_price_historical(symbol, comparison_symbol, limit, aggregate, exchange=''):
        url = 'https://min-api.cryptocompare.com/data/histohour?fsym={}&tsym={}&limit={}&aggregate={}'\
                .format(symbol.upper(), comparison_symbol.upper(), limit, aggregate)
        if exchange:
            url += '&e={}'.format(exchange)
        page = requests.get(url)
        data = page.json()['Data']
        df = pd.DataFrame(data)
        df['timestamp'] = [datetime.datetime.fromtimestamp(d) for d in df.time]
        df = df.drop('time', 1)
        df.set_index('timestamp')
        return df
    
    
    data = {}
    tickers = ['BTC', 'ETH', 'XRP']                 # pools of tickers to get
    for t in tickers:                                                           # a loop to get data ticker by ticker
        data[t] = hour_data = hourly_price_historical(t,'USD', 9999999,1)       # calling the function defined above
        print("Getting the data for: ", t)
        globals()['df_' + str(t)] = data
    

    【讨论】:

      猜你喜欢
      • 2018-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 1970-01-01
      • 2021-07-02
      • 2019-03-11
      • 1970-01-01
      相关资源
      最近更新 更多