【问题标题】:How to produce a flatfile (?) from a hierarchical csv如何从分层 csv 生成平面文件(?)
【发布时间】:2013-09-02 20:51:35
【问题描述】:

我需要对一个结构如下的csv做一些数据处理:

我需要为 FIELD 条目为空的行折叠 TEXT 列中的所有数据,并使其看起来像这样:

FIELD              TEXT

P0190001, RACE OF HOUSEHOLDER BY HOUSEHOLD TYPE(8) Universe:Households White Family Households: Married-couple family: With related children

P0190002, RACE OF HOUSEHOLDER BY HOUSEHOLD TYPE(8) Universe:Households White Family Households: Married-couple family: No related children

...等等。(FIELD中第一个有效条目之前的空白条目数并不总是两个,可能或多或少)

对于大型(60,000 个独特的“字段”)csv 文件,是否有一种简单有效的方法来执行此操作?我正在寻找在命令行上执行此操作而不是编写程序的方法。

【问题讨论】:

  • LH 列是否会随着每个新类别而变化?
  • LH 列确实发生了变化,但完全无关紧要。我不需要它。
  • 如果您有 60,000 个,LH 允许您为类别编制索引。你能发布一个更大的样本吗?

标签: python shell csv data-structures text-files


【解决方案1】:

这不是一个命令行解决方案,而是一个有趣的脚本。

import csv

csv_reader = csv.reader(open('data.csv', 'rb'))

# Read first two rows of field text out as a prefix.                            
prefix = ' '.join(csv_reader.next()[2].strip() for i in range(2))

def collapsed_row_iter():
    depth_value_list = []
    for (_, field_id, field_text, _) in csv_reader:
        # Count number of leading <SPACE> chars to determine depth.             
        pre_strip_text_len = len(field_text)
        field_text = field_text.lstrip()
        depth = pre_strip_text_len - len(field_text)

        depth_value_list_len = len(depth_value_list)
        if depth == depth_value_list_len + 1:
            # Append a new depth value.                                            
            depth_value_list.append(field_text.rstrip())

        if depth <= depth_value_list_len:
            # Truncate list to depth, append new value.                         
            del depth_value_list[depth:]
            depth_value_list.append(field_text.rstrip())

        else:
            # Depth value is greater than current_depth + 1                     
            raise ValueError

        # Only yield the row if field_id value is non-NULL.                     
        if field_id:
            yield (field_id, '%s %s' % (prefix, ' '.join(depth_value_list)))

# Get CSV writer object, write the header.                                      
csv_writer = csv.writer(open('collapsed.csv', 'wb'))
csv_writer.writerow(['FIELD', 'TEXT'])

# Iterate over collapsed rows, writing each to the output CSV.                  
for (field_id, collapsed_text) in collapsed_row_iter():
    csv_writer.writerow([field_id, collapsed_text])

输出:

FIELD,TEXT
P0190001,RACE OF HOUSEHOLDER BY HOUSEHOLD TYPE (8) Universe: Households White Family Households: Married-couple family: With related children
P0190002,RACE OF HOUSEHOLDER BY HOUSEHOLD TYPE (8) Universe: Households White Family Households: Married-couple family: No related children
P0190003,"RACE OF HOUSEHOLDER BY HOUSEHOLD TYPE (8) Universe: Households White Family Households: Other family: Male householder, no wife present: With related children"
P0190004,"RACE OF HOUSEHOLDER BY HOUSEHOLD TYPE (8) Universe: Households White Family Households: Other family: Male householder, no wife present: No related children"

【讨论】:

  • 嗨,derek,这个脚本看起来不错,但我无法编译它。我得到的消息是:``Traceback(最近一次调用最后一次):文件“C:\ collapse.py”,第40行,在中为collapsed_row_iter()中的(field_id,collapsed_text):文件“C:\collapse .py",第 28 行,在collapsed_row_iter 中引发 ValueError ValueError ` field_id 从哪里获取它的值?我没有看到它被初始化。对不起,我不知道任何 python。
  • 此错误在第 28 行的 else 子句中由语句 raise ValueError 显式引发,该语句在代码遇到比当前级别深 >1 级的深度级别时执行.我添加了这个子句是因为我不确定你想如何处理这种情况。 field_id 由语句 for (_, field_id, field_text, _) in csv_reader: 分配。 csv_reader 是一个迭代器,它返回文件中每一行的列值列表。请注意,此语句需要 4 个列值并将 1 和 4 分配给名为“_”的一次性变量。
  • 哦,我最终设法修复了它。前两行实际上不是前缀,而是整个层次结构的一部分;但我考虑到了这一点,也稍微改变了检测新水平的逻辑。它完美地工作。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多