根据条件将当前行与前面的若干行合并
我正在尝试修复收到的一个CSV文件,其中实际的换行符被插入到数据中,实际把一行数据拆成多行,导致列不完整。换行符被放在一个完整单词后的空格处,而不是留一个空格。
由于地区设置,十进制点用逗号表示(见列E 和F)。
A列中的日期可能会重复出现,但需要保持为独立的记录。
input.csv, raw:
A date;B string;C string;D string;E integer;F integer
08.01.2026;a;b;c;3,7;
;d;;f;;
;e;;;;
;;;;;
08.01.2026;g;h;i;2,11;
;;;j;;
;;;k;;
31.01.2026;l;m;n;8,0;
03.02.2026;o;p;q;;4,9
;;r;s;;
input.csv:
| (index) | A date | B string | C string | D string | E integer | F integer |
|---|---|---|---|---|---|---|
| 0 | 08.01.2026 | a | b | c | 3,7 | |
| 1 | d | f | ||||
| 2 | e | |||||
| 3 | ||||||
| 4 | 08.01.2026 | g | h | i | 2,11 | |
| 5 | j | |||||
| 6 | k | |||||
| 7 | 31.01.2026 | l | m | n | 8,0 | |
| 8 | 03.02.2026 | o | p | q | 4,9 | |
| 9 | r | s |
期望输出(用空白替代被移除的换行):
| (index) | A date | B string | C string | D string | E integer | F integer |
|---|---|---|---|---|---|---|
| 0 | 08.01.2026 | a d e | b | c f | 3,7 | |
| 4 | 08.01.2026 | g | h | i j k | 2,11 | |
| 7 | 31.01.2026 | l | m | n | 8,0 | |
| 8 | 03.02.2026 | o | p r | q s | 4,9 |
import pandas as pd
df1 = pd.read_csv("input.csv", sep=";")
只要我不对 input.csv 进行排序,所有数据基本上都保持在正确的位置。我有两种解决思路:
-
遍历所有行。如果第一列A 中有任何值,则跳到下一行。
-
如果在列A 中也有值,则i-1行是正确的(参见:第7 行是正确的)。
- 如果列A 的值为空 / "",则i-1行不正确,缺失的数据可以在当前行中找到。将第i 行的数据与第i-1行的对应列合并在一起,并删除第i 行(参见:第0 行不完整,需要把第1 行和第2 行合并到/与第0 行连接)。
- 如果整行都是空的,则删除该行(参见:第3 行)。
用来判断这两种情况的逻辑已经在那里,但我实在想不出把两行数据叠加/拼接/合并在一起的方法。
-
创建两个不同的数据框:
-
df1包含原始数据:
none A date;B string;C string;D string;E integer;F integer 08.01.2026;a;b;c;3,7; ;d;;f;; ;e;;;; ;;;;; 08.01.2026;g;h;i;2,11; ;;;j;; ;;;k;; 31.01.2026;l;m;n;8,0; 03.02.2026;o;p;q;;4,9 ;;r;s;;* df2包含原始数据,但向上移动1 行:none A date;B string;C string;D string;E integer;F integer ;d;;f;; ;e;;;; ;;;;; 08.01.2026;g;h;i;2,11; ;;;j;; ;;;k;; 31.01.2026;l;m;n;8,0; 03.02.2026;o;p;q;;4,9 ;;r;s;;
如果df2[A] 为空,则将整行与df1中的相应行进行融合/拼接/合并。但这和变体1 的问题一样,因为我还没找到一种“覆盖”两行数据的方式。
我找到的最接近的类似问题是 get previous row's value and calculate new column pandas python。它是在做整数相减,但我现在是在尝试把字符串连接起来。
解决方案
让你的input.csv作为df(尽管我不太确定你到底是怎么解析的),并以日期列作为分组标识符,你可以这样做:
df.index = df["A date"].notna().cumsum().rename()
res = df.fillna("").groupby(level=0).agg(lambda x: "".join(list(x)))
print(res)
结果:
A date B string C string D string E integer F integer
1 08.01.2026 ade b cf 3,7
2 08.01.2026 g h ijk 2,11
3 31.01.2026 l m n 8,0
4 03.02.2026 o pr qs 4,9
是的,你可以根据需要使用 column:agg_function 字典作为 .agg() 载荷来聚合每一列(请参见 Scott Boston的回答 中的示例)。