簡體   English   中英

谷歌表格 API 和 Pandas。 來自 API 的數據長度不一致

[英]Google Sheets API and Pandas. Inconsistent data length from the API

我正在使用谷歌表格 API 來獲取數據,然后將其傳遞給 Pandas 以便我可以輕松地處理數據。

假設我想獲得一張包含以下數據的表格(描述為 JSON object,因為這里沒有很好地展示表格)

{
  columns: ['Name', 'Age', 'Tlf.' 'Address'],
  data: ['Julie', '35', '12345', '8 Leafy Street']
}

工作表 API 將返回以下內容:

{
  'range': 'Cases!A1:AE999',
   'majorDimension': 'ROWS',
    'values': 
    [
            ['Name', 'Age', 'Tlf.', 'Address'],
      ['Julie', '35', '12345', '8 Leafy Street']
    ]
}

這很棒,讓我可以輕松地將列標題和數據傳遞給 Pandas,而不用大驚小怪。 我通過以下方式執行此操作:

values = sheets_api_result["values"]
df = pd.DataFrame(values[1:], columns=values[0])
我的問題

如果我有一個如下表所示的 Gsuite 工作表,描述為 key:value 數據類型

{
  'range': 'Cases!A1:AE999',
   'majorDimension': 'ROWS',
    'values': 
    [
            ['Name', 'Age', 'Tlf.', 'Address'],
      ['Julie', '35']
    ]
}

我會收到以下回復

{ 'range': 'Cases:A1,AE999': 'majorDimension', 'ROWS': 'values', [ ['Name', 'Age'. 'Tlf,', 'Address'], ['Julie', '35'] ] }

請注意,兩個 arrays 的長度不相等,並且返回的不是Nonenull值,響應中根本不存在數據。

在我的代碼中處理這些數據時,我最終得到一個看起來像這樣的錯誤

ValueError: 4 columns passed, passed data had 2 columns

據我所知,我有兩個選擇:

  1. 想出一個聰明的方法在必要時用None填充我的響應
  2. If possible, instruct the API to return a null value in the JSON where null values exist, especially when the last column(s) have no data at all.

關於第 1 點。我想我可以將 append x None值添加到x等於length_of_column_heading_array - length_of_data_array的列表中。 然而,這確實看起來很丑陋,也許有一種更優雅的方式來做到這一點。

關於第 2 點,我還沒有找到對我有幫助的答案。

如果有人對我如何解決這個問題有任何想法,我將不勝感激。

干杯!

如果有人感興趣,這就是我解決問題的方法。

首先,我們需要從表格 API 中獲取所有數據。

# define the names of the tabs I want to get
ranges = ['tab1', 'tab2']

# Call the Sheets API
request = service.spreadsheets().values().batchGet(spreadsheetId=document, ranges=ranges,)
response = request.execute()

現在我想通過每一列 go 並確保每一行的列表包含與包含列標題的第一行相同數量的元素。

# response is the response from google sheets API, 
# and from the code above. It contains column headings
# and data from every row.

# valueRanges is the key to access the data.
def extract_case_data(response, keyword):
    for obj in response["valueRanges"]:
        if keyword in obj["range"]:
            values = pad_data(obj["values"])
            df = pd.DataFrame(values[1:], columns=values[0])
            return df
    return None

最后,填充數據的方法

def pad_data(data: list):

    # build a new array with the column heading data
    # this is the list which we will return
    return_data = [data[0]]

    for row in data[1:]:
        difference = len(data[0]) - len(row)
        new_row = row
        # append None to the lists which have a shorter
        # length than the column heading list
        for count in range(1, difference + 1):
            new_row.append(None)
        return_data.append(new_row)
    return return_data

我當然不是說這是最好或最優雅的解決方案,但它已經為我解決了問題。

希望這可以幫助某人。

同樣的想法,也許看起來更簡單:

獲取原始值

result = service.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=data_range).execute()
raw_values = result.get('values', [])

然后在迭代時完成

for row in raw_values:
    row = row + [''] * (expected_length - len(row))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM