根据第n列中的值拆分无序的csv文件/

时间:2016-12-21 16:54:18

标签: python csv

我有一个大的csv文件,其中包含代表几种不同物种的采样病原体的信息。我想按物种分割这个csv文件,所以每个物种我会有一个csv文件。文件中的数据不以任何特定顺序排列。我的csv文件如下所示:

.service.consul

物种名称为5号。

我最初尝试过这个:

# Python Imports
import os
from socket import error as SocketError, timeout as SocketTimeout

# 3rd Party Imports
from dns import resolver
from requests.packages.urllib3.connection import HTTPConnection
from requests.packages.urllib3.exceptions import (NewConnectionError,
                                                  ConnectTimeoutError)
from requests.packages.urllib3.util import connection

def resolve_srv_record(host):

    consul_dns_ip_port = os.environ.get('CONSUL_DNS_IP_PORT', 
                                        '172.17.0.1:53')
    consul_dns_ip, consul_dns_port = consul_dns_ip_port.split(':')

    res = resolver.Resolver()
    res.port = consul_dns_port
    res.nameservers = [consul_dns_ip]

    ans = resolver.query(host, 'SRV')

    return ans.response.additional[0].items[0].address, ans[0].port

def patched_new_conn(self):

    if self.host.endswith('.service.consul'):
        hostname, port = resolve_srv_record(self.host)
    else:
        hostname = self.host
        port = self.port

    extra_kw = {}

    if self.source_address:
        extra_kw['source_address'] = self.source_address

    if self.socket_options:
        extra_kw['socket_options'] = self.socket_options

    try:
        conn = connection.create_connection((hostname, port),
                                            self.timeout,
                                            **extra_kw)

    except SocketTimeout as e:
        raise ConnectTimeoutError(
            self, "Connection to %s timed out. (connect timeout=%s)" %
            (self.host, self.timeout))

    except SocketError as e:
        raise NewConnectionError(
            self, "Failed to establish a new connection: %s" % e)

    return conn

def requests_use_srv_records():
    HTTPConnection._new_conn = patched_new_conn

但这失败了,因为数据没有按物种排序,并且没有输出的附加争论(我知道)所以每次脚本遇到一个新的条目它已经写入文件的物种会覆盖第一个条目。

是否有一种简单的方法按物种排序数据然后执行上述脚本或将上述脚本的输出附加到文件而不是覆盖它的方法?

另外,我理想地将每个输出文件命名为它们包含的物种。

感谢。

2 个答案:

答案 0 :(得分:2)

参考你的评论:"没有输出的附加议案(我知道的)",你可以使用' a' ;而不是' w'附加到文件,如:

with open("%s.csv" % key, "a")

可能不是最好的方法,因为如果你运行代码两次,你会把所有东西都翻倍。

答案 1 :(得分:2)

您可以使用与groupby operation使用相同的lambda函数对csv文件进行排序:

import csv
from itertools import groupby

groupfunc = lambda row: row[5]

for key, rows in groupby(sorted(csv.reader(open("file.csv")),key=groupfunc),groupfunc):
    with open("%s.csv" % key, "w") as output:
        cw = csv.writer(output)
        cw.writerows(rows)

注意:

  1. 我重写了写例程,使用csv模块作为输出
  2. 我为你的lambda创建了一个变量,所以没有复制粘贴
  3. 请注意,如果更改输入数据,则必须清理csv文件,因为如果新数据中没有一个物种,旧的csv将保留在磁盘上。我想用一些代码来表达:

    import glob,os
    
    for f in glob.glob("*.csv"):
       os.remove(f)
    

    但请注意*.csv模式,因为它太宽,而且对其他csv文件可能有点太有效了:)

    注意:此方法使用sort,因此需要更多内存。您可以选择以附加模式打开每个文件,而另一个解决方案建议保存内存,但执行更多文件I / O.