【问题标题】:How to split values in a CSV file如何拆分 CSV 文件中的值
【发布时间】:2020-09-17 13:42:18
【问题描述】:

我有一个如下所示的 CSV 文件。现在它没有任何列,它包含一些我实际上不需要的字段,所以我需要根据一些条件将它写入一个新文件。

!PROJECT1, OBJECT1
2020-09-10+02:00,100,HHH,SAS,RM$20,1,1
2020-09-16+02:00,200,GGG,SAS,TAKE,2020-09-16+02:00
2020-09-13+02:00,300,TTT,SAS,TAKE,2020-09-13+02:00
2020-09-11+02:00,100,HHH,SAS,RM$20,1,1

这些是条件:

  1. 如果index[4] 包含单词TAKE,我只会写记录。如果是这样,请选择index[0][4][5]
  2. 索引[0]和[5]需要在YEARMONTHDAYTD中被吐出并命名。 index[4] 需要命名为 TYPE

我希望我的新文件如下所示:

YEAR    MONTH    DAY    TD    TYPE    YEAR    MONTH    DAY    TD 
2020    09       16     2     TAKE     2020    09       16     2
2020    09       13     2     TAKE     2020    09       13     2

这是我的代码:

def filter_row(r):
    condition_1 = r[4] == 'TAKE' #<-- take only the TAKE's

with open(file_path, 'r') as my_file, open('outputfile.txt', 'w') as outer:
        reader = csv.reader(my_file, delimiter = ',')
        next(reader) #Skip the first row because it's just the header
        writer = csv.writer(outer, delimiter = '\t')
        for row in reader:            
                if filter_row(row):
                writer.writerow(row)

现在我的输出文件如下所示:

2020-09-16+02:00,  200,  GGG,   SAS,  TAKE,  2020-09-16+02:00
2020-09-13+02:00,  300,  TTT,   SAS,  TAKE,  2020-09-13+02:00

【问题讨论】:

  • 使用pandas。容易得多。
  • @YashShah 被告知使用 CSV,因为我有超过 35000 行和超过 25 列
  • r[4] is 'TAKE' - 你应该在这里使用== 而不是isstackoverflow.com/q/1504717/3282436
  • @0x5453 是的,我已经改了,但是其他的呢?

标签: python csv file split


【解决方案1】:

这里有两个任务。首先过滤数据,然后解析数据得到需要的值。

过滤可以使用内置的filter 函数(或list comprehensiongenerator expression,如果您愿意)。对于解析,可以使用一个小函数,因为我们需要每行处理两个日期。

operator.itemgetter 用于有效地从行中提取数据。

import csv
import operator

# Get the value of the 'take' column
type_getter = operator.itemgetter(4)
# Extract the columns we want to work with
columns_getter = operator.itemgetter(0, 4, 5)


def process_datestring(datestring):
    # Assumes offset is always positive; consider
    # using re.split if it could be positive or negative.
    date, _, offset = datestring.partition('+')
    dateparts = date.split('-')
    td, *_ = offset.partition(':')
    dateparts.append(td)
    return dateparts


headers = ['YEAR', 'MONTH', 'DAY', 'TD', 'TYPE', 'YEAR', 'MONTH', 'DAY', 'TD']
with open(file_path, 'r') as my_file, open('outputfile.txt', 'w') as outer:
    reader = csv.reader(my_file, delimiter = ',')
    next(reader) #Skip the first row because it's just the header
    writer = csv.writer(outer, delimiter = '\t')

    writer.writerow(headers)

    filtered = filter(lambda r: type_getter(r) == 'TAKE', reader)
    for row in filtered:
        date1, type_, date2 = columns_getter(row)
        out_row = process_datestring(date1)
        out_row.append(type_)
        out_row.extend(process_datestring(date2))
        writer.writerow(out_row)

【讨论】:

    【解决方案2】:

    你可以写一个解析函数。像这样的:

    def parser(row):
        if "TAKE" in row[4]: #Checks for your 'TAKE' statement
            year = row[0][0:4]
            month = row[0][5:7]
            ...
            year_2 = row[5][0:4]
            ...
            return [year, month, day, td, row[4], year_2, month_2,...]
    

    把这一切交给你的作者:

    for row in reader:
        converted = parser(row)
        writer.writerow(converted)
    

    这应该可行。如果您想更加小心,则必须使用 strptime 将字符串转换为 datetime.datetime 对象,然后提取日期,但如果切分字符串足够好,您可以这样做。

    【讨论】:

    • 它没有提供所需的输出。我仍然得到所有的行,没有任何东西被分割。
    猜你喜欢
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    相关资源
    最近更新 更多