如何将上面一行的“X”或“Y”值添加到缺少该值的行中?

How can I add the "X" or "Y" value from a line above to the line that is missing the value?

提问人:volk.SWAG.en 提问时间:11/9/2023 最后编辑:volk.SWAG.en 更新时间:11/9/2023 访问量:79

问:

我有一个具有此结构的 .csv 文件:

X310.433,Y9.6

X310.54,Y10

X143.52型

X144.77型

当一行中没有“X”或“Y”值时,我想从上面的行中获取该值并将其复制到之后的行中,即缺少该值。 在此示例中,将 Y10 复制到下一行,并用逗号分隔。 我怎样才能用python做到这一点?

python 读取.csv

评论

0赞 Ada 11/9/2023
如果 X 和 Y 都在一条线上,那么 X 会一直排在第一位吗?即是否有可能有一条像这样的线?Y9.6,X310.433
0赞 volk.SWAG.en 11/9/2023
不,X 永远是第一个。但是有些行只有 Y 值,所以 Y 会排在第一位。
1赞 CtrlZ 11/9/2023
如果前两行有 X 值但没有 Y 值,会发生什么情况?您的想法是重写 CSV 文件并添加缺失值吗?

答:

0赞 Mortz 11/9/2023 #1

您可以简单地将最新看到的和值存储在变量中 -xy

csv_str = '''
X310.433,Y9.6 
X310.54,Y10   
X143.52       
X144.77       
,Y71.21       
Y27           
'''
csv_file = io.StringIO(csv_str) # You'd probably do csv_file = open('fielname.csv', 'r') here instead of io.StringIO
for line in csv_file:
    if line.strip():
        xvals = [val for val in line.strip().split(',') if val.startswith('X')]
        yvals = [val for val in line.strip().split(',') if val.startswith('Y')]
        if xvals:
            latest_x = xvals.pop()
        if yvals:
            latest_y = yvals.pop()
        print(latest_x, latest_y, sep=',')

输出

X310.433,Y9.6
X310.54,Y10
X143.52,Y10
X144.77,Y10
X144.77,Y71.21
X144.77,Y27

或者,您可以使用该模块而不是 - 我发现这更具可读性,但是 YMMV -restartswith

for line in csv_file:
    if line.strip():
        xvals = re.search(r'X\d+\.?\d+', line.strip())
        yvals = re.search(r'Y\d+\.?\d+', line.strip())
        if xvals:
            latest_x = xvals.group()
        if yvals:
            latest_y = yvals.group()
        print(latest_x, latest_y, sep=',')

评论

1赞 user19077881 11/9/2023
该代码不标识 X 和 Y 值,而是按位置标识。因此,如果缺少 X 值(OP 需要这种可能性),则代码不会使用上行中的 X 值。
0赞 volk.SWAG.en 11/9/2023
是的,它只复制 Y 值。有没有办法修改它,以便在只有 Y 时它也会复制 X 值?
0赞 Mortz 11/9/2023
确实如此,对吧?请参阅我示例中的最后一行 - 我假设即使缺少 X 值,Y 值也会在逗号之后。@volk。SWAG.en - 不是这样吗?,Y71.21
0赞 volk.SWAG.en 11/9/2023
不,事实并非如此。很抱歉没有提到这一点。
0赞 user19077881 11/9/2023
可以修改代码以用于将 X 和 Y 值与分割线分开。startswith()
0赞 chaiz 11/9/2023 #2
import pandas as pd

df = pd.read_csv('a.csv', names=['X', 'Y'])
df.fillna(method='ffill', inplace=True)
df.to_csv('ret.csv', index=False, header=False)

评论

0赞 user19077881 11/9/2023
该代码不标识 X 和 Y 值,而是按位置标识。因此,如果缺少 X 值(OP 要求这种可能性并且没有前导逗号),则代码不会使用上一行中的 X 值。
0赞 Nikhil S 11/9/2023 #3

试试这个:

import pandas as pd

df = pd.read_excel('loc to your csv/your_csv.xlsx')  

print(df)
df['a'] = df['a'].apply(lambda x: x.split(','))
print(df)
x1 = df.loc[0, 'a'][0].split(',')[0][1:]
y1 = df.loc[0, 'a'][1].split(',')[0][1:]
x2 = df.loc[1, 'a'][0].split(',')[0][1:]
y2 = df.loc[1, 'a'][1].split(',')[0][1:]
m=(float(y2)-float(y1))/(float(x2)-float(x1))
c=float(y1)-(m*float(x1))

y3=(m*float(df.loc[2,'a'][0][1:]))+c
y4=(m*float(df.loc[3,'a'][0][1:]))+c

print(f'{y3}{y4}')

df.loc[2]='X'+str(df.loc[2,'a'][0][1:])+'Y'+str(y3)
df.loc[3]='X'+str(df.loc[3,'a'][0][1:])+'Y'+str(y4)


df.to_csv('loc to output/output.csv', index=False)
1赞 CtrlZ 11/9/2023 #4

在没有任何实用程序模块的情况下,您可以这样做:

假设文件内容为:

X310.433,Y9.6
Y999
X310.54,Y10

X143.52

X144.77

...然后。。。

lines: list[tuple[str, str]] = []

with open("foo.csv") as foo:
    for line in map(str.strip, foo):
        if line:
            a, *b = line.split(",")
            if a[0] == "X":
                if b:
                    lines.append((a, b[0]))
                else:
                    lines.append((a, lines[-1][1]))
            else:
                assert a[0] == "Y"
                if b:
                    lines.append((b[0], a))
                else:
                    lines.append((lines[-1][0], a))
for line in lines:
    print(",".join(line))

输出:

X310.433,Y9.6
X310.433,Y999
X310.54,Y10
X143.52,Y10
X144.77,Y10

注意:

如果文件的第一行包含 X 或 Y 之一(但不能同时包含两者),则此操作将失败

编辑:

重写原始文件的更强大版本:

with open("foo.csv", "r+") as foo:
    lines: list[tuple[str, str]] = []
    for line in map(str.strip, foo):
        if line:
            a, *b = line.split(",")
            if a.startswith("X"):
                y = b[0] if b else lines[-1][1]
                lines.append((a, y))
            elif a.startswith("Y"):
                x = b[0] if b else lines[-1][0]
                lines.append((x, a))
    foo.seek(0)
    for line in lines:
        print(",".join(line), file=foo)
    foo.truncate()

评论

0赞 volk.SWAG.en 11/9/2023
with open(“foo.csv”) as foo: “as foo” 有什么作用?
1赞 CtrlZ 11/9/2023
@volk。SWAG.en 看看 docs.python.org/3/reference/compound_stmts.html 并熟悉上下文管理器