对齐CSV的行

7jmck4yq  于 2023-09-28  发布在  其他
关注(0)|答案(1)|浏览(66)

我有一个三列的CSV。每一列都有基本相同的数据,但偶尔会有一个条目丢失,因此列中的所有内容都向上移动,行变得不对齐。我想创建CSV,以便每行都有相同的条目。我选择“bash”和“python”作为flair,因为我知道它们安装在我的Linux机器上。任何其他可以在没有第三方工具的情况下在Linux机器上工作的方法都将被接受。
例如,我有这个CSV:

1,2,1
3,3,2
4,5,5
6,6,7
7,7,8
8,8,9

我想把它改成

1,,1
,2,2
3,3,
4,,
,5,5
6,6,
7,7,7
8,8,8
,,9

在初始CSV中,每列按字母/数字排序。
输出中的每一行可以在该行的任意数量的列中具有相同的值。例如,在第一行中,-1可以在列1、2或3或它们中的任何一个中。我不想在第一行第二列“添加”1。我想插入一个空白到第一行,第二列推动每一个条目的第二列下来。这样,所有的“二”都在同一行上(对于具有二的列)并且所有的“三”都在同一行上,等等。
我的CSV中的实际值与上面的不同。我使用上面的值来保持简单。如果有必要的话,我的值将最多为15个字母数字字符,后跟一个下划线,然后是三个数字。示例:ABCDE14915_429。如果你觉得更现实的价值观会成为一个更好的例子,它们是:
输入

ABCDE12345_001,FGHIJ6789_002,ABCDE12345_001
KLMNO5432_003,KLMNO5432_003,FGHIJ6789_002
PQRST24680_123,UVWXY13579_555,UVWXY13579_555,
ZABCD876530_009,ZABCD876530_009,7
AABBCCDDEE_987,AABBCCDDEE_987,LMNOP98765_999
LMNOP98765_999,ZYXWV54321_777,ZYXWV54321_777

输出

ABCDE12345_001,,ABCDE12345_001
,FGHIJ6789_002,FGHIJ6789_002
KLMNO5432_003,KLMNO5432_003,
PQRST24680_123,,
UVWXY13579_555,UVWXY13579_555,
ZABCD876530_009,ZABCD876530_009,
AABBCCDDEE_987,AABBCCDDEE_987,AABBCCDDEE_987
LMNOP98765_999,,LMNOP98765_999
,ZYXWV54321_777,ZYXWV54321_777

也许这张照片会有帮助。列ABC是我的输入CSV值。我想输出CSV值看起来像列EFG。

或者如果你喜欢“真实的”的价值观

xn1cxnb4

xn1cxnb41#

我选择了一个不需要任何排序的解决方案:它只是寻找一个值,并记住它出现在哪一列(在任何一行)。
从这个输入开始:

a,b,a
c,c,b
d,e,e
f,f,g
g,g,h
h,h,i

它生成一个值到位置的Map:

{
    "a": [0, 2],
    "b": [1, 2],
    "c": [0, 1],
    "d": [0],
    "e": [1, 2],
    "f": [0, 1],
    "g": [2, 0, 1],
    "h": [2, 0, 1],
    "i": [2],
}

从Map中,它迭代值,并将每个值写入其自己的行,在找到的位置(列)中:

a,,a
,b,b
c,c,
d,,
,e,e
f,f,
g,g,g
h,h,h
,,i

由于它不预设排序,因此:

b,a,a
d,d,d
c,e,e

变成:

{
    "b": [0],
    "a": [1, 2],
    "d": [0, 1, 2],
    "c": [0],
    "e": [1, 2],
}

变成:

b,,
,a,a
d,d,d
c,,
,e,e

这(格式为易读性):

| ABCDE12345_001  | FGHIJ6789_002   | ABCDE12345_001 |
| KLMNO5432_003   | KLMNO5432_003   | FGHIJ6789_002  |
| PQRST24680_123  | UVWXY13579_555  | UVWXY13579_555 |
| ZABCD876530_009 | ZABCD876530_009 | AABBCCDDEE_987 |
| AABBCCDDEE_987  | AABBCCDDEE_987  | LMNOP98765_999 |
| LMNOP98765_999  | ZYXWV54321_777  | ZYXWV54321_777 |

变成:

| ABCDE12345_001  |                 | ABCDE12345_001 |
|                 | FGHIJ6789_002   | FGHIJ6789_002  |
| KLMNO5432_003   | KLMNO5432_003   |                |
| PQRST24680_123  |                 |                |
|                 | UVWXY13579_555  | UVWXY13579_555 |
| ZABCD876530_009 | ZABCD876530_009 |                |
| AABBCCDDEE_987  | AABBCCDDEE_987  | AABBCCDDEE_987 |
| LMNOP98765_999  |                 | LMNOP98765_999 |
|                 | ZYXWV54321_777  | ZYXWV54321_777 |
import csv
from collections import defaultdict

value_positions = defaultdict(list)

with open("input4.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        for i, val in enumerate(row):
            value_positions[val].append(i)

N_COLS = 3

with open("output.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    for val, positions in value_positions.items():
        row = [""] * N_COLS
        for x in positions:
            row[x] = val
        writer.writerow(row)

相关问题