在解析Pandas中的csv文件时,如何从字符串中删除额外的空格?

mpj*_*jan 49 python parsing pandas

我有以下名为'data.csv'的文件:

    1997,Ford,E350
    1997, Ford , E350
    1997,Ford,E350,"Super, luxurious truck"
    1997,Ford,E350,"Super ""luxurious"" truck"
    1997,Ford,E350," Super luxurious truck "
    "1997",Ford,E350
    1997,Ford,E350
    2000,Mercury,Cougar
Run Code Online (Sandbox Code Playgroud)

我想将它解析为pandas DataFrame,以便DataFrame如下所示:

       Year     Make   Model              Description
    0  1997     Ford    E350                     None
    1  1997     Ford    E350                     None
    2  1997     Ford    E350   Super, luxurious truck
    3  1997     Ford    E350  Super "luxurious" truck
    4  1997     Ford    E350    Super luxurious truck
    5  1997     Ford    E350                     None
    6  1997     Ford    E350                     None
    7  2000  Mercury  Cougar                     None
Run Code Online (Sandbox Code Playgroud)

我能做的最好的事情是:

    pd.read_table("data.csv", sep=r',', names=["Year", "Make", "Model", "Description"])
Run Code Online (Sandbox Code Playgroud)

哪个让我:

    Year     Make   Model              Description
 0  1997     Ford    E350                     None
 1  1997    Ford     E350                     None
 2  1997     Ford    E350   Super, luxurious truck
 3  1997     Ford    E350  Super "luxurious" truck
 4  1997     Ford    E350   Super luxurious truck 
 5  1997     Ford    E350                     None
 6  1997     Ford    E350                     None
 7  2000  Mercury  Cougar                     None
Run Code Online (Sandbox Code Playgroud)

如何在没有这些空格的情况下获取DataFrame?

unu*_*tbu 49

你可以使用转换器:

import pandas as pd

def strip(text):
    try:
        return text.strip()
    except AttributeError:
        return text

def make_int(text):
    return int(text.strip('" '))

table = pd.read_table("data.csv", sep=r',',
                      names=["Year", "Make", "Model", "Description"],
                      converters = {'Description' : strip,
                                    'Model' : strip,
                                    'Make' : strip,
                                    'Year' : make_int})
print(table)
Run Code Online (Sandbox Code Playgroud)

产量

   Year     Make   Model              Description
0  1997     Ford    E350                     None
1  1997     Ford    E350                     None
2  1997     Ford    E350   Super, luxurious truck
3  1997     Ford    E350  Super "luxurious" truck
4  1997     Ford    E350    Super luxurious truck
5  1997     Ford    E350                     None
6  1997     Ford    E350                     None
7  2000  Mercury  Cougar                     None
Run Code Online (Sandbox Code Playgroud)


The*_*ist 28

添加参数skipinitialspace=Trueread_table为我工作.

所以尝试:

pd.read_table("data.csv", 
              sep=r',', 
              names=["Year", "Make", "Model", "Description"], 
              skipinitialspace=True)
Run Code Online (Sandbox Code Playgroud)

同样适用于pd.read_csv().

  • 尽管转换器可以完成更多任务,但对于大多数用例而言,人们想要的是“ skipinitialspace = True”。可能应该是最佳答案! (3认同)

Bre*_*arn 27

嗯,空白在你的数据中,所以你不能在不读取空格的情况下读入数据.但是,在您阅读之后,您可以通过执行删除空格,例如,df["Make"] = df["Make"].map(str.strip)(df您的数据框在哪里).


RKD*_*314 11

我没有足够的声誉留下评论,但如果您有NaN值,上面的答案建议使用该map功能strip将无法工作,因为条带仅适用于字符,NaN是浮点数.

有一个内置的pandas功能来实现这一点,我用过: 你的数据帧pd.core.strings.str_strip(df['Description'])
在哪里df.就我而言,我在大约120万行的数据帧上使用它,速度非常快.


小智 8

我不认为在此问题发布时Pandas对此表示支持,但最直接的方法是在sep参数中使用regex read_csv。因此,类似以下的内容应该可以解决此问题。

table = pd.read_table("data.csv", sep=' *, *')
Run Code Online (Sandbox Code Playgroud)

  • 这很好用,但在 jupyter 中也需要参数 ```engine="python"``` 否则它会转储混乱的警告 ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 个字符且不同于 '\s+' 被解释为正则表达式); (2认同)

J W*_*ang 5

这是一个迭代每一列并应用的函数pd.core.strings.str_strip

def df_strip(df):
  df = df.copy()
  for c in df.columns:
    if df[c].dtype == np.object:
      df[c] = pd.core.strings.str_strip(df[c])
    df = df.rename(columns={c:c.strip()})
  return df
Run Code Online (Sandbox Code Playgroud)


Raj*_*ddy 5

read_table弃用,这是文档中出现的消息。

自 0.24.0 版起已弃用。

使用pandas.read_csv()代替,如有必要,传递 sep='\t' 。

因此,使用read_csv您可以传入sep参数的正则表达式,您可以在其中将分隔符指定为

sep="\s*,\s*"
Run Code Online (Sandbox Code Playgroud)

任意数量的空格,然后是分隔符,然后是任意数量的空格,这将确保所有前导和尾随空格也被选为分隔符块,进而删除数据两侧的空格.

正则表达式详情如下:

\s -> white-space
* -> any number (zero or many)
, -> no meaning, direct character match
Run Code Online (Sandbox Code Playgroud)

因此,正则表达式\s*,\s*代表white-space[any number] match a comma and white-space[any number]

如果您的分隔符不是逗号,则,用您的分隔符替换上述表达式中的 。例如:\s*;\s*如果;是您的分隔符。