提问人:volk.SWAG.en 提问时间:11/9/2023 最后编辑:volk.SWAG.en 更新时间:11/9/2023 访问量:79
如何将上面一行的“X”或“Y”值添加到缺少该值的行中?
How can I add the "X" or "Y" value from a line above to the line that is missing the value?
问:
我有一个具有此结构的 .csv 文件:
X310.433,Y9.6
X310.54,Y10
X143.52型
X144.77型
当一行中没有“X”或“Y”值时,我想从上面的行中获取该值并将其复制到之后的行中,即缺少该值。 在此示例中,将 Y10 复制到下一行,并用逗号分隔。 我怎样才能用python做到这一点?
答:
0赞
Mortz
11/9/2023
#1
您可以简单地将最新看到的和值存储在变量中 -x
y
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 -re
startswith
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 并熟悉上下文管理器
评论
Y9.6,X310.433