我如何读取CSV的最后n列与pandas的坏行?

klsxnrf1  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(113)

我在尝试使用pandas读取CSV文件时遇到了一个问题。CSV结构如下:

Col1, Col2, Col3, Col4
a1, a2, a3, a4, a5
b1, b2, b3, b4, b5
c1, c3, c4, c5
d1, d2, d3, d4, d5

字符串
某些行包含缺失值,我特别希望只提取每行的最后n单元格,因为这些单元格保证存在。在给定的示例中,其中n=3,所需的DataFrame应该如下所示:

Col3 Col4 Col5
0   a3   a4   a5
1   b3   b4   b5
2   c3   c4   c5
3   d3   d4   d5


我尝试使用usecols=[2,3,4],但结果是N/A值:

Col3  Col4  Col5
0    a3    a4    a5
1    b3    b4    b5
2    c4    c5   NaN
3    d3    d4    d5


任何关于如何达到预期结果的指导都将不胜感激。谢谢您的帮助!

4urapxun

4urapxun1#

为了好玩,你可以尝试regex分隔符:

N = 3 # last N columns

pat = r".+?{}?$".format("([^,]+),"*N)

df = pd.read_csv(file, sep=pat, engine="python").dropna(how="all", axis=1)

字符串
输出量:

print(df)

   Col2  Col3  Col4
0    a3    a4    a5
1    b3    b4    b5
2    c3    c4    c5
3    d3    d4    d5

w8biq8rn

w8biq8rn2#

直接在read_csv级别处理这个问题是很困难的。一个选项可能是加载所有数据,然后重新调整它:

df = pd.read_csv(data)

mask = df.notna().loc[:, ::-1].cummax(axis=1).loc[:, ::-1]

out = pd.DataFrame(df.to_numpy()[np.arange(len(df))[:,None],
                                 np.argsort(mask)],
                   index=df.index, columns=df.columns
                  )

字符串
输出量:

Col1  Col2  Col3  Col4
a1   a2    a3    a4    a5
b1   b2    b3    b4    b5
c1  NaN    c3    c4    c5
d1   d2    d3    d4    d5


然后,您可以仅选择所需的列
如果只想处理最后的n列:

last_col = 3

mask = df.notna().iloc[:, :-last_col-1:-1].cummax(axis=1).iloc[:, ::-1]

out = df.copy()
out.iloc[:, -last_col:] = (df
                     .iloc[:, -last_col:]
                     .to_numpy()[np.arange(len(df))[:,None],
                                 np.argsort(mask)])


输出量:

Col1  Col2  Col3  Col4
a1   a2    a3    a4    a5
b1   b2    b3    b4    b5
c1   c3   NaN    c4    c5
d1   d2    d3    d4    d5

lymnna71

lymnna713#

如果pandas不是必需的,我想我会使用CSV包和默认阅读器来挑选每行的最后三列:
比如说:

import io
import csv

data = """
Col1,Col2,Col3,Col4
a1,a2,a3,a4,a5
b1,b2,b3,b4,b5
c1,c3,c4,c5
d1,d2,d3,d4,d5
""".strip()

with io.StringIO(data) as file_in:
    reader = csv.reader(file_in)
    headers = next(reader)  # not sure if you want/nead the header
    rows = [row[-3:] for row in reader] # the last three columns

字符串
现在,您可以使用rows做您喜欢的事情

for row in rows:
    print(row)


会给你给予:

['a3', 'a4', 'a5']
['b3', 'b4', 'b5']
['c3', 'c4', 'c5']
['d3', 'd4', 'd5']

ix0qys7i

ix0qys7i4#

如果你只是想提取每一行最后一个单元格的值,那么你可以使用下面的代码来获取每一行的最后一个单元格。
代码:

import pandas as pd
from io import StringIO

csv_data = """
Col1, Col2, Col3, Col4
a1, a2, a3, a4, a5
b1, b2, b3, b4, b5
c1, c3, c4, c5
d1, d2, d3, d4, d5
"""

df = pd.read_csv(StringIO(csv_data))

last_values = df.apply(lambda row: row.dropna().iloc[-1] if not row.dropna().empty else pd.NA, axis=1)

for _, value in zip(last_values.index, last_values):
    print(value)

字符串
“df = pd.read_csv(StringIO(csv_data))”此行使用pd.read_csv函数将CSV数据读入Pandas DataFrame(df)。StringIO(csv_data)用于将字符串csv_data转换为pd.read_csv可以读取的类似文件的对象。
“last_values = df.apply(lambda行:row.dropna().iloc[-1] if not row.dropna().empty else pd.NA,axis=1)”这里,通过对DataFrame(df)的每一行应用lambda函数来创建一个名为last_values的新Series。lambda函数使用row.dropna()检查该行是否具有任何非空值。如果它不为空,它使用iloc[-1]提取最后一个非空值。如果该行为空,则分配pd.NA(Pandas对缺失值的表示)。
“for _,value in zip(last_values.index,last_values):print(value)“最后,循环迭代last_values系列的索引和值,并打印每个值。该循环实际上打印原始DataFrame的每行中的最后一个非空值。

相关问题