将Google表格CSV导入Pandas数据框架

79
我把一个文件上传到Google电子表格(以使一个包含数据的公开IPython笔记本成为一个公开范例)。 我正在使用原始格式的文件,可以将其读入Pandas Dataframe。现在我使用下面的代码来读取电子表格,它可以正常工作,但只是以字符串的形式呈现,我试图将它转换回Dataframe却没有成功(您可以获取数据)。

我将一个文件上传到了Google电子表格中(以制作一个可公开访问的IPython笔记本,带有数据示例),并且我正在使用原始文件格式,可以将其读入Pandas Dataframe。现在,我使用以下代码读取电子表格,虽然可以正常工作,但是数据仅以字符串的形式呈现,并且我尝试将其转换回Dataframe时没有成功(您可以获取数据)。

import requests
r = requests.get('https://docs.google.com/spreadsheet/ccc?key=0Ak1ecr7i0wotdGJmTURJRnZLYlV3M2daNTRubTdwTXc&output=csv')
data = r.content
数据看起来像这样:(第一行是标题)
',City,region,Res_Comm,mkt_type,Quradate,National_exp,Alabama_exp,Sales_exp,Inventory_exp,Price_exp,Credit_exp\n0,Dothan,South_Central-Montgomery-Auburn-Wiregrass-Dothan,Residential,Rural,1/15/2010,2,2,3,2,3,3\n10,Foley,South_Mobile-Baldwin,Residential,Suburban_Urban,1/15/2010,4,4,4,4,4,3\n12,Birmingham,North_Central-Birmingham-Tuscaloosa-Anniston,Commercial,Suburban_Urban,1/15/2010,2,2,3,2,2,3\n

负责将磁盘文件引入的本机熊猫代码如下:

df = pd.io.parsers.read_csv('/home/tom/Dropbox/Projects/annonallanswerswithmaster1012013.csv',index_col=0,parse_dates=['Quradate'])

提供一种“干净”的解决方案会有很多帮助,可以轻松地共享数据集用于Pandas!我尝试了许多替代方案,但都没有成功,我相信我可能又错过了一些明显的东西。

更新说明:新的Google电子表格具有不同的URL模式。只需在上面的示例中使用此URL或下面的答案即可,您应该没问题,这是一个示例:

https://docs.google.com/spreadsheets/d/177_dFZ0i-duGxLiyg6tnwNDKruAYE-_Dd8vAQziipJQ/export?format=csv&id
请看下面@Max Ghenis的解决方案,只使用了pd.read_csv,不需要StringIO或requests...

1
你是怎么从谷歌云盘上获取csv链接的? - Mugen
只需在浏览器中打开电子表格并复制URL即可。 - dartdog
URL以/edit?ts=5c0e311e#gid=0结尾,共享链接以/edit?usp=sharing结尾,两者均不包含csv,当通过pandas代码请求时,两者都会返回404 - Mugen
在文档菜单中使用“下载为CSV” - dartdog
10个回答

82

似乎我不需要使用 StringIO:

test = pd.read_csv('https://docs.google.com/spreadsheets/d/' + 
                   '0Ak1ecr7i0wotdGJmTURJRnZLYlV3M2daNTRubTdwTXc' +
                   '/export?gid=0&format=csv',
                   # Set first column as rownames in data frame
                   index_col=0,
                   # Parse column values to datetime
                   parse_dates=['Quradate']
                  )
test.head(5)  # Same result as @TomAugspurger

顺便提一下,包括?gid=可以导入不同的表格,从URL中找到对应的gid。


1
也许只需要添加注释说明index_col和parse_dates是做什么的?此外,可能很明显,但我认为这只适用于公共电子表格;如果不是,则必须使用API。 - getup8
4
好的解决方案。当表格被分享为“任何人有此链接可以查看”时可用。请注意,index_colparse_dates参数是可选的。 - Dylan Hogg
3
只有当电子表格是公开的时候才能正常工作。 - Marco Cerliani

65

您可以在StringIO对象上使用read_csv()函数:

from io import BytesIO

import requests
import pandas as pd

r = requests.get('https://docs.google.com/spreadsheet/ccc?key=0Ak1ecr7i0wotdGJmTURJRnZLYlV3M2daNTRubTdwTXc&output=csv')
data = r.content
    
In [10]: df = pd.read_csv(BytesIO(data), index_col=0,parse_dates=['Quradate'])

In [11]: df.head()
Out[11]: 
          City                                            region     Res_Comm  \
0       Dothan  South_Central-Montgomery-Auburn-Wiregrass-Dothan  Residential   
10       Foley                              South_Mobile-Baldwin  Residential   
12  Birmingham      North_Central-Birmingham-Tuscaloosa-Anniston   Commercial   
38       Brent      North_Central-Birmingham-Tuscaloosa-Anniston  Residential   
44      Athens                 North_Huntsville-Decatur-Florence  Residential   

          mkt_type            Quradate  National_exp  Alabama_exp  Sales_exp  \
0            Rural 2010-01-15 00:00:00             2            2          3   
10  Suburban_Urban 2010-01-15 00:00:00             4            4          4   
12  Suburban_Urban 2010-01-15 00:00:00             2            2          3   
38           Rural 2010-01-15 00:00:00             3            3          3   
44  Suburban_Urban 2010-01-15 00:00:00             4            5          4   

    Inventory_exp  Price_exp  Credit_exp  
0               2          3           3  
10              4          4           3  
12              2          2           3  
38              3          3           2  
44              4          4           4  

1
我寻找了数周如何将电子表格导入 Pandas 中。从未听说过 requests 或 StringIO 库。谢谢! - moldovean
5
为了澄清"在Python3中如果你在使用它,可能会被移动的":从 io 中导入 StringIO。 - ezcodr
谢谢!但是我必须使用这种形式的Google URL来进行CSV输出:https://dev59.com/_mEi5IYBdhLWcg3whcri#23702001 - nealmcb
如何指定表格(即URL中的#gid=x)?在key=后直接添加它到URL本身并不起作用。 - Max Ghenis
从@Max Ghenis中查看以下与程序相关的内容 - dartdog
显示剩余2条评论

22

在浏览器中打开你需要的特定表格。确保任何人都可以通过链接至少查看它。复制并粘贴URL。你会得到类似于https://docs.google.com/spreadsheets/d/BLAHBLAHBLAH/edit#gid=NUMBER的东西。

sheet_url = 'https://docs.google.com/spreadsheets/d/BLAHBLAHBLAH/edit#gid=NUMBER'

首先我们将它转换为一个 CSV 导出 URL,例如 https://docs.google.com/spreadsheets/d/BLAHBLAHBLAH/export?format=csv&gid=NUMBER

csv_export_url = sheet_url.replace('/edit#gid=', '/export?format=csv&gid=')

然后我们将其传递给 pd.read_csv,它可以接受 URL。

df = pd.read_csv(csv_export_url)

如果Google更改其API(似乎没有文件记录),那么这将会出现问题,并且如果网络故障发生,可能会给出无用的错误信息。


这段代码返回一个HTML页面,用于下载gsheet中的csv文件,而不是直接返回csv文件。 - diegodsp
16
我遇到了ParserError错误:数据的分词出现问题。C错误:第6行应该有1个字段,但是却看到了2个字段。 - rsc05
你确定将访问权限设置为“任何有链接的人”了吗? - Raisin

12

我的方法有点不同。我只是使用了pandas.Dataframe(),但显然需要安装和导入gspread。它运行得很好!

gsheet = gs.open("Name")
Sheet_name ="today"
wsheet = gsheet.worksheet(Sheet_name)
dataframe = pd.DataFrame(wsheet.get_all_records())

不错..界面越来越简洁了! - dartdog
5
为了澄清,gs 将是 gs = gspread.authorize(credentials) 的结果。 - RAbraham

7

我一直在使用以下工具,目前它们都能正常工作:

def load_from_gspreadsheet(sheet_name, key):
    url = 'https://docs.google.com/spreadsheets/d/{key}/gviz/tq?tqx=out:csv&sheet={sheet_name}&headers=1'.format(
        key=key, sheet_name=sheet_name.replace(' ', '%20'))

    log.info('Loading google spreadsheet from {}'.format(url))

    df = pd.read_csv(url)
    return df.drop([col for col in df.columns if col.startswith('Unnamed')], axis=1)

您需要指定表格名称和关键词。关键词是您从以下路径的URL中获取的字符串:https://docs.google.com/spreadsheets/d/{key}/edit/

如果您有多行列名,则可以更改标题的值,但我不确定是否仍适用于多个标题。

如果Google更改其API,则可能会出现故障。

请注意,您的电子表格必须是公共的,拥有链接的所有人都可以阅读它。


5

首先

import pandas as pd
pd.read_csv("https://docs.google.com/spreadsheets/d/e/{}/pub?gid=0&single=true&output=csv")

被低估但简单的答案。 - Shaida Muhammad
这对我有用,谢谢!但是这只读取第一个工作表。我怎样才能读取所有的工作表? - Sergey Belousov

5

简洁明了:

  • 获取您的谷歌URL

https://docs.google.com/spreadsheets/d/ 这是您的表格ID号码,/edit?gid=这将是您的选项卡名称,它将是一个数字。每个选项卡都有自己的

我喜欢创建一个函数(此处不创建),以便分离我的变量

  • sheet_id = "在此输入您的表格ID"
  • sheet_name = "在此输入您的表格#"

下面的URL是棘手的部分:

url = f"https://docs.google.com/spreadsheets/d/{sheet_id}/export?gid={sheet_name}&format=csv"

然后只需读取它

df = pd.csv(url)

就是这样。如果您需要选择不同的行作为标题,则可以执行以下操作

df = pd.csv(url,header=1)


2
请使用"df = pd.read_csv(url)"代替"df = pd.csv(url)"。 - Robb Dunlap
太好了 @RobbDunlap ,我记不得为什么我使用 pd.csv 而不是在那里放入 "read"。 - JQTs

3
如果csv文件是通过Drive共享而不是通过电子表格共享,则以下更改URL的方法将起作用。
#Derive the id from the google drive shareable link.
#For the file at hand the link is as below
#<https://drive.google.com/open?id=1-tjNjMP6w0RUV4GhJWw08ql3wYwsNU69>
file_id='1-tjNjMP6w0RUV4GhJWw08ql3wYwsNU69'
link='https://drive.google.com/uc?export=download&id={FILE_ID}'
csv_url=link.format(FILE_ID=file_id)
#The final url would be as below:-
#csv_url='https://drive.google.com/uc?export=download&id=1-tjNjMP6w0RUV4GhJWw08ql3wYwsNU69'
df = pd.read_csv(csv_url)

如果您刚刚运行了上面的代码,那么数据框应该是这样的:

    a   b   c   d
0   0   1   2   3
1   4   5   6   7
2   8   9   10  11
3   12  13  14  15

可以在这里查看可运行的代码。


3
在 Google Sheets 文件中,转到“文件”>“发布到Web”>选择 .csv(请参见屏幕截图)>复制链接。 Google Sheets:发布到Web 代码
import pandas as pd

path = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vSvmELTzIjfSmX8GuV3HE2qomN3uRyvPX8RDzpw77JH33DUbj1bjech7H6NYPArvpZFux0DdJ5L5TKy/pub?output=csv'
data = pd.read_csv(path)
print(data)

在Google Colab中的代码


3

这对我有效。

import pandas as pd

#Create a public URL
#https://docs.google.com/spreadsheets/d/0Ak1ecr7i0wotdGJmTURJRnZLYlV3M2daNTRubTdwTXc/edit?usp=sharing

#get spreadsheets key from url
gsheetkey = "0Ak1ecr7i0wotdGJmTURJRnZLYlV3M2daNTRubTdwTXc"

#sheet name
sheet_name = 'Sheet 1'

url=f'https://docs.google.com/spreadsheet/ccc?key={gsheetkey}&output=xlsx'
df = pd.read_excel(url,sheet_name=sheet_name)
print(df)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接