pd.Read_csv忽略括号内的逗号



我有一个非常简单的文件:

[Name]
Streamline 1

[Data]
X [ m ], Y [ m ], Z [ m ], Velocity [ m s^-1 ]
2.66747564e-01, 0.00000000e+00, 2.03140453e-01, (0.00000000e+00, 8.17744827e+00, 0.00000000e+00)
2.66958952e-01, 0.00000000e+00, 2.07407191e-01, (0.00000000e+00, 6.77392197e+00, 0.00000000e+00)
2.63460875e-01, 0.00000000e+00, 2.06593186e-01, (0.00000000e+00, 7.04168701e+00, 0.00000000e+00)
2.65424699e-01, 0.00000000e+00, 2.00831652e-01, (0.00000000e+00, 8.93691921e+00, 0.00000000e+00)
2.70607203e-01, 0.00000000e+00, 2.02286631e-01, (0.00000000e+00, 8.45830917e+00, 0.00000000e+00)
2.68299729e-01, 0.00000000e+00, 1.97365344e-01, (0.00000000e+00, 1.00771456e+01, 0.00000000e+00)
...

我需要将速度作为矢量加载到单行中。

基本代码:

df = pd.read_csv("C:/Users/Marek/Downloads/0deg-5ms.csv", skiprows=5)

但是这个尝试导致前2个cols成为索引,其余的分成4列。index_col=False可以解决索引问题,但会导致索引超出范围。我需要一个分隔符来隐式地告诉pandas忽略括号中的内容。我认为python在读取csv文件时忽略括号内的分隔符可能会起作用,但是是的,我到处都有空格。我发现了一些使用扩展函数来加载文件并按行处理它们的解决方案,例如包含括号中偶尔有逗号的列的CSV文件崩溃了pandas。read_csv和将带有圆括号包围的数据的CSV加载到pandas数据框架中。然而,我相信这是一个非常简单的场景,因为所有的行都是相似的,可以通过添加delimiter='some_regex'的一行代码来解决。然而,我不能弄清楚,如何这个正则表达式应该看起来。它应该查找分隔符,而不是(.*,.*)

我已经尝试了以下操作,但这导致了单列:

df = pd.read_csv("C:/Users/Marek/Downloads/0deg-5ms.csv", skiprows=5,  delimiter=',^((.*,.*))')

编辑:得到了这样的东西-,|(?:((.*,.*))),但这在每个逗号后面添加了一个空列。

您可以手动解析文件:

data = []
with open('data.csv') as fp:
[next(fp) for i in range(5)]  # skiprows=5
headers = [c.strip() for c in next(fp).split(',')]
for line in fp:
data.append([i.strip() for i in re.split(r',(?![^(]*[)])', line)])
df = pd.DataFrame(data, columns=headers).apply(pd.eval)

输出:

>>> df
X [ m ]  Y [ m ]   Z [ m ]     Velocity [ m s^-1 ]
0  0.266748      0.0  0.203140  [0.0, 8.17744827, 0.0]
1  0.266959      0.0  0.207407  [0.0, 6.77392197, 0.0]
2  0.263461      0.0  0.206593  [0.0, 7.04168701, 0.0]
3  0.265425      0.0  0.200832  [0.0, 8.93691921, 0.0]
4  0.270607      0.0  0.202287  [0.0, 8.45830917, 0.0]
5  0.268300      0.0  0.197365  [0.0, 10.0771456, 0.0]
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6 entries, 0 to 5
Data columns (total 4 columns):
#   Column               Non-Null Count  Dtype  
---  ------               --------------  -----  
0   X [ m ]              6 non-null      float64
1   Y [ m ]              6 non-null      float64
2   Z [ m ]              6 non-null      float64
3   Velocity [ m s^-1 ]  6 non-null      object 
dtypes: float64(3), object(1)
memory usage: 320.0+ bytes
>>> type(df.iloc[0, 3])  # [0.0, 8.17744827, 0.0]
list
>>> type(df.iloc[0, 3][1])  # 8.17744827
float

经过多次尝试,我找到了如何创建一个非常简单的一行代码的答案。如果有人感兴趣的话,这里是:

df = pd.read_csv("C:/Users/Marek/Downloads/0deg-5ms.csv", skiprows=5,  delimiter=',(?![^(]*[)])', engine="python")

Delimiter检查括号外的所有内容中是否有逗号。简单如魅力:)