将pandas dtypes转换为BigQuery类型表示

时间:2014-02-19 16:39:44

标签: python numpy pandas google-bigquery

我刚刚安装了大熊猫和numpy,并且没有任何经验。我正在尝试获得类似于传递给Google BigQuery所需的json数据结构。 https://developers.google.com/bigquery/docs/reference/v2/jobs#configuration.load.encoding

目标

  1. 确定data_types
  2. 返回JSON,其中key是列名,值是其中一种数据类型:STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP or RECORD
  3. 我尝试了什么

     import numpy as np                                                              
     import pandas as pd                                                             
     import config                                                                   
     import boto                                                                     
     from StringIO import StringIO                                                   
    
     k = boto.connect_s3(**config.AWS_PARAMS).get_bucket('xxxxxxx').get_key('DATA.csv')                                          
     o = StringIO(k.get_contents_as_string())                                             
     df = pd.read_csv(o)                                                             
    
     def map_dtype(dtype):                                                                                                                                 
         if dtype.kind == 'i':                                                       
             # [int8, int16, int32, int64]                                           
             return "INTEGER"                                                        
         elif dtype.kind == 'u':                                                     
             # [uint8, uint16, uint32, uint64]                                       
             return "INTEGER"                                                        
         else:                                                                       
             return "STRING"                                                         
    
     fields = []                                                                     
     for c, d  in zip(df.columns, df.dtypes):                                        
             field = {}                                                              
             field['type'] = map_dtype(d)                                            
             field['name'] = c                                                       
             fields.append(field)                                                    
    
    
     print fields
    

    结果

    [{'type': 'INTEGER', 'name': 'VALUE'}, {'type': 'INTEGER', 'name': 'ID'}, {'type': 'STRING', 'name': 'Key'}, {'type': 'STRING', 'name': 'EmailAddress'}]
    

    如你所见,我得到了正确的结果。但我不喜欢我是怎么做的。我觉得有一种更简单的方法可以做到这一点。

    我想改进什么

    1. map_dtype()函数,如您所见,我必须使用BigQuery中的字符串表示手动映射数据类型
    2. For each loop,感觉应该有一种更简单的方法来将data_type分配给列。

2 个答案:

答案 0 :(得分:3)

好消息!由于版本0.13 pandas正式(和实验)支持Google BigQuery。

检查read_gbq,特别是to_gbq(将数据放入BigQuery):http://pandas.pydata.org/pandas-docs/stable/api.html#google-bigquery

此处的示例笔记本的视频和链接:

(谢谢Pearson!)

答案 1 :(得分:2)

我不确定pandas.io.gbq中的方法会对您有多大帮助。如果我理解正确,您有一个CSV文件,并且您正在尝试将dtypes映射到BigQuery类型。据我在pandas.io.gbq工作时发现,没有一种非常方便的方法可以做到这一点。

有关numpy类型的有用列表,请参阅: http://docs.scipy.org/doc/numpy/reference/arrays.interface.html#arrays-interface

  

基本类型字符代码为:

     
      
  • t位字段(跟随整数给出位字段中的位数)。
  •   
  • b布尔值(所有值仅为True或False的整数类型)
  •   
  • i Integer
  •   
  • u无符号整数
  •   
  • f浮点
  •   
  • c复杂浮点
  •   
  • O Object(即内存包含指向PyObject的指针)
  •   
  • S String(固定长度的char序列)
  •   
  • U Unicode(Py_UNICODE的固定长度序列)
  •   
  • V其他(无效* - 每个项目是固定大小的内存块)
  •   

在这种情况下,我觉得字典是查找的最佳选择,您可以用列表解析替换for循环:

df = DataFrame({'a' : [1,2], 'b' : [True, False], 'c' : [1.1, 2.1], 'd' : ['a', 'b']})
type_dict = {
    'b' : 'BOOLEAN',
    'i' : 'INTEGER',
    'f' : 'FLOAT',
    'O' : 'STRING',
    'S' : 'STRING',
    'U' : 'STRING'
}
[{'name' : col_name, 'type' : type_dict.get(col_type.kind, 'STRING')} for (col_name, col_type) in df.dtypes.iteritems()]

收率:

[{'type': 'INTEGER', 'name': 'a'}, {'type': 'BOOLEAN', 'name': 'b'}, {'type': 'FLOAT', 'name': 'c'}, {'type': 'STRING', 'name': 'd'}]

在这种情况下,我在dict中明确引用'O','S'和'U' - 你可以通过多种方式处理这个问题。显然,需要注意“O”情况,因为它可能没有有用的字符串表示。同样,由于我使用.get()方法,我假设不支持类型的字符串表示优于什么。这可能不是你的情况(或者你可能希望避免可能的类型继续前进),因此最好直接查找值type_dict[col_type]并根据具体情况处理异常