以CSV格式处理数据

时间:2016-01-12 21:58:53

标签: csv python-3.x pandas

使用Python 3和numpy,我正在尝试阅读和操作CSV。我的目的是找到超过50,000平方英尺的所有建筑物,其数据位于第6列。解释器返回一个错误,指出“Line#(得到1列而不是11列)。”我认为我的问题是将数据类型注册为字符串,但我尝试了不同的数据类型,无法让脚本工作。

import numpy as np
dataframe = np.genfromtxt('buildingsv1.csv', dtype=str, skip_header=1, delimiter="none",usecols=(6))
headers = next(dataframe)
for row in dataframe: 
    if 50000 in row(6):
       print(row)
np.savetxt('buildingsv2')

解决方案(使用Pandas代替Numpy)

import pandas as pd
total_df = pd.read_csv('buildingsv1.csv', keep_default_na=False, na_values=[""])
#Build new DataFrame of 4 columns
total_df[['PARCELID', 'KIVAPIN', 'ADDRESS', 'APN']]   
total_df[total_df.sqft >= 50000] 

raw dataset的版本可用。我使用的是具有机器可读标题和更多列的桌面版本。

2 个答案:

答案 0 :(得分:0)

这是使用Pandas(基于Numpy构建)的一般概念。

import pandas as pd
import numpy as np

# I generated df below but you'd want to read the data with pd.read_csv() like so
#df = pd.read_csv('buildingsv1.csv')

df = pd.DataFrame(np.random.rand(10, 6)*100000,
                  columns=['Column'+str(i) for i in range(1, 7)])

new_df = df[df['Column6'] >= 50000]

最好使用dtypes检查Pandas中的df.dtypes。您的数据首先需要数字才能过滤50,000以上。

如果您的数字数据有逗号(例如:50,000),则可能会出现问题。这是一个包含逗号的列的示例。

>>> df1 = pd.DataFrame({'Other Data': [2, 3, 44, 5, 65, 6], 'Commas1': [' 68,028,616 ', ' 162,470,071 ', ' 135,393,045 ', ' 89,981,894 ', ' 74,787,888 ', ' 173,610,498 ']})
>>> df1
         Commas1  Other Data
0    68,028,616            2
1   162,470,071            3
2   135,393,045           44
3    89,981,894            5
4    74,787,888           65
5   173,610,498            6

>>> df1.dtypes
Commas1       object
Other Data     int64
dtype: object

转换Commas1列的一种方法是使用正则表达式:

df1['Commas1'] = df1['Commas1'].str.replace(r'[^\d\.]', '').astype('int64')

>>> df1
     Commas1  Other Data
0   68028616           2
1  162470071           3
2  135393045          44
3   89981894           5
4   74787888          65
5  173610498           6
>>> df1.dtypes
Commas1       int64
Other Data    int64
dtype: object

在本例中,Commas1已被转换为整数数据类型。例如,如果您需要浮点数而不是整数,则可以将int64更改为float64

答案 1 :(得分:0)

这是一个以逗号分隔的csv(带有numpy)运行的示例

使用行列表模拟文件。

In [168]: txt="""name, val1, val2, val3
me, 23, 34, 34
you, 34, 22, 35
he, 22, 66, 66
she, 36,32,36
"""
In [169]: txt=txt.splitlines()

加载genfromtxt

In [170]: data = np.genfromtxt(txt,dtype=None, delimiter=',')
In [171]: data
Out[171]: 
array([['name', ' val1', ' val2', ' val3'],
       ['me', ' 23', ' 34', ' 34'],
       ['you', ' 34', ' 22', ' 35'],
       ['he', ' 22', ' 66', ' 66'],
       ['she', ' 36', '32', '36']], 
      dtype='|S5')

oops,它加载了字符串 - 因为第一行是名称。

略过第一行:

In [174]: data = np.genfromtxt(txt,dtype=None, skip_header=1,delimiter=',')
In [175]: data
Out[175]: 
array([('me', 23, 34, 34), ('you', 34, 22, 35), ('he', 22, 66, 66),
       ('she', 36, 32, 36)], 
      dtype=[('f0', 'S3'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')])

它正确地推断了列类型,但给了它们通用名称。 names=True使用文件中的列标题:

In [176]: data = np.genfromtxt(txt,dtype=None, names=True,delimiter=',')
In [177]: data
Out[177]: 
array([('me', 23, 34, 34), ('you', 34, 22, 35), ('he', 22, 66, 66),
       ('she', 36, 32, 36)], 
      dtype=[('name', 'S3'), ('val1', '<i4'), ('val2', '<i4'), ('val3', '<i4')])

data是一个1d数组,有4条记录;这些记录的字段在dtype

中定义

现在我们可以根据一些列标准显示此数组中的行:

In [179]: for row in data:
    if row['val2']>32:
        print(row)
   .....:         
('me', 23, 34, 34)
('he', 22, 66, 66)

一条记录:

In [181]: data[0]
Out[181]: ('me', 23, 34, 34)

一个字段(列):

In [182]: data['name']
Out[182]: 
array(['me', 'you', 'he', 'she'], 
      dtype='|S3')

可以将这些选定的值收集到一个新数组中,其表达式如下:

In [205]: data1=data[data['val2']>32]
In [206]: data1
Out[206]: 
array([('me', 23, 34, 34), ('he', 22, 66, 66)], 
      dtype=[('name', 'S3'), ('val1', '<i4'), ('val2', '<i4'), ('val3', '<i4')])

使用csv编写匹配的numpy并不是很好。它有一个savetxt,用于在列中写入数据,但您必须指定格式和标题。

In [207]: header='name, val1, val2, val3'
In [208]: fmt='%10s, %4d, %4d, %4d'
In [209]: np.savetxt('test.csv',data1, fmt=fmt,header=header)
In [210]: cat test.csv
# name, val1, val2, val3
     'me',   23,   34,   34
     'he',   22,   66,   66