【问题标题】:Cannot update Google Sheet from Dataframe -- json issue, single cell issue无法从 Dataframe 更新 Google 表格 - json 问题,单个单元格问题
【发布时间】:2021-07-18 13:56:58
【问题描述】:

我有一个数据框,我想将其非标题记录附加到谷歌表格。

import gspread
import csv

latest = pd.read_csv("/Users/sam/Downloads/transactions.csv")

updatesheet = sheet.worksheet("testpy")

updatesheet.append_row([update], table_range='A1')

这给出了Object of type DataFrame is not JSON serializable的错误

我尝试了各种堆栈线程的其他选项,大多数会导致非 JSON 类型错误,但是当我转换 df.to_json() 时,它会将其全部放入一个单元格中。

编辑:更新 table_range='A1:A' 没有修复。

【问题讨论】:

  • 尝试更改范围。您当前正在传递一个单元格作为范围。 A1 是一个单元格。尝试不使用范围...如果这不起作用,请尝试A:ZZ。这应该足够宽,除非 CSV 文件中有很多列
  • 另外,请查看this answer,了解如何使用 gspread 直接加载 CSV。
  • 再想一想,要在工作表中添加单列,将表格范围更改为A1:A。那是一个范围而不是一个单元格...
  • @EdoAkse 没有修复它。我在帖子中的代码给出了一个 DataFrame 类型的 Object is not JSON serializable 的错误。如果我把它变成 to_json 那就是当它把所有东西都插入一个单元格的时候。按照建议更新范围并不能解决此问题。
  • 您能打印出经过清理的 CSV 文件行吗?以及您希望在 GSheets 中看到的屏幕截图?另外,您使用 pandas 的具体原因有哪些?

标签: python json pandas dataframe google-sheets


【解决方案1】:

我可以在这里想到两种方法,我在下面都包括了。

您遇到的 JSON 类型错误可以通过 casting 将 df 行作为列表解决,如 method2 所示。

只需省略table_range,即可解决将所有内容放入单元格A1 的问题。

import gspread
import pandas as pd


# set variables
docid = 'yourdocidhere'
worksheetid = 'transactions'
credfile = 'path/to/file/credentials.json'
csvfile = 'path/to/file/transactions.csv'


# load GSheet
gc = gspread.service_account(filename=credfile)
sheet = gc.open_by_key(docid)
worksheet = sheet.worksheet(worksheetid)


# load CSV file into df
df_csv = pd.read_csv(csvfile)


def method1(worksheet: gspread.Worksheet, df: pd.DataFrame):
    """This is the 'cheaty' way. Just load the existing worksheet
    into df, append other df and overwrite existing worksheet.
    Note that this doesn't check if the values in df are already
    in the worksheet...

    Args:
        worksheet (gspread.Worksheet): the worksheet with which to work
        df (pd.DataFrame): the df to append
    """
    # just load existing GSheet into a df
    df_cheat = pd.DataFrame(worksheet.get_all_records())
    # perform append. You might want to play with how you merge/append
    # This method has the advantage of easy sorting.
    df_cheat = df_cheat.append(df).sort_values(by='Date')
    # overwrite worksheet
    # you could easily create a new worksheet with this method as you have
    # the df_cheat to work with
    worksheet.update([df_cheat.columns.values.tolist()] + df_cheat.values.tolist())


def method2(worksheet: gspread.Worksheet, df: pd.DataFrame):
    """This method goes through the df row by row and adds
    it to the worksheet by using casting.
    https://www.w3schools.com/python/python_casting.asp

    Args:
        worksheet (gspread.Worksheet): the worksheet with which to work
        df (pd.DataFrame): the df to append
    """
    # go over the values in the df by row
    for row in df.values:
        # cast as list
        row = list(row)
        # if you leave out the table_range it will append at the end
        worksheet.append_row(row)


method1(worksheet, df_csv)
method2(worksheet, df_csv)

path/to/file/transactions.csv

Date,Time,Amount,Type,Description,Category
4/1/2019,21:49:02,-$11,Withdrawal,Intuit,*QuickBooks Work - Organization

之前 之后

【讨论】:

  • 很棒的方法 2 是我想要的,效果很好!仅供参考,我首先摄取现有的工作表数据,然后与最新的 csv 进行比较,以确定我需要插入的最新数据。为了进行比较,我将日期列转换为日期时间。您的方法为 datetime 列提供了 json 错误,因此我在调用该方法之前将其转换回字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 2017-03-25
  • 1970-01-01
  • 2012-10-05
  • 1970-01-01
相关资源
最近更新 更多