Python 在Pandas中解析csv文件时,如何从字符串中删除额外的空白?
我有一个名为“data.csv”的文件:Python 在Pandas中解析csv文件时,如何从字符串中删除额外的空白?,python,parsing,pandas,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,Mer
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
我想将其解析为一个pandas数据框,以便该数据框如下所示:
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
\s -> white-space
* -> any number (zero or many)
, -> no meaning, direct character match
我所能做的就是:
pd.read_table("data.csv", sep=r',', names=["Year", "Make", "Model", "Description"])
这让我感到:
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
如果没有这些空白,我如何获取数据帧?嗯,空白在数据中,因此如果不读取空白,就无法读取数据。但是,读入后,您可以通过执行以下操作去除空白,例如,
df[“Make”]=df[“Make”].map(str.strip)
(其中df
是您的数据帧)。您可以使用转换器:
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)
屈服
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
我没有足够的声誉留下评论,但是上面的答案建议使用
map
函数和strip
如果您有NaN值,将不起作用,因为strip只对char有效,而NaN是float
有一个内置的pandas函数来实现这一点,我使用了:
pd.core.strings.str_strip(df['Description'])
其中,
df
是您的数据帧。在我的例子中,我在大约120万行的数据帧上使用了它,速度非常快。添加参数skipinitialspace=True
因此,请尝试:
pd.read_table("data.csv",
sep=r',',
names=["Year", "Make", "Model", "Description"],
skipinitialspace=True)
在
pd.read\u csv()
中也可以使用同样的方法。这里有一个函数,用于迭代每列并应用pd.core.strings.str\u 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
str.strip()函数在Series上运行得非常好。因此,我将包含空格的dataframe列转换为一个系列,使用str.strip()函数去除空格,然后将转换后的列替换回dataframe。下面是示例代码
import pandas as pd
data = pd.DataFrame({'values': [' ABC ', ' DEF', ' GHI ']})
new = pd.Series([])
new = data['values'].str.strip()
data['values'] = new
我不相信Pandas在发布此问题时支持这一点,但最直接的方法是在
read\u csv
的sep
参数中使用regex。因此,类似于以下内容的内容应该适用于此问题
table = pd.read_table("data.csv", sep=' *, *')
已弃用,以下是文档中显示的消息
自版本0.24.0以来已弃用
如有必要,请改用传递sep='\t'
因此,使用read\u csv可以为sep
参数传入一个正则表达式,其中可以将分隔符指定为
sep="\s*,\s*"
任意数量的空格,后跟分隔符,再后跟任意数量的空格,这将确保所有前导空格和尾随空格也被选为分隔符块,从而删除数据两侧的空白
regex详情如下:
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
\s -> white-space
* -> any number (zero or many)
, -> no meaning, direct character match
因此,正则表达式\s*,\s*
代表空格[任何数字]匹配逗号和空格[任何数字]
如果分隔符不是逗号,则用分隔符替换上述表达式中的
,
。例如:\s*\s*
如果
是您的分隔符。这对我很有帮助。我在数据中有像“NaN”这样的值,这使得它能够检测到NaN,而不管“NaN”前面有多大的空白,也不需要手动设置“na_值”参数。虽然转换器可以做到这一点,但对于大多数用例,skipinitialspace=True
是人们想要的。应该是最好的答案!更简单的是data['values']=data['values'].str.strip()
非常有用,尤其是当输出到不需要头或索引的txt文件时。这是唯一有效的解决方案df[“Make”]=df[“Make”].map(str.strip)
然后我将df.to_csv('no_head.txt',header=None,index=False)
这消除了空白。再次感谢这项工作很好,但在jupyter中还需要参数engine=“python”
,或者它会转储混乱的警告解析警告:返回到“python”引擎,因为“c”引擎不支持正则表达式分隔符(分隔符>1个字符,与“\s+”不同的分隔符被解释为正则表达式);这个答案很老套。“没有足够的声誉”。目前有595和一个金色徽章如果您在CSV文件中引用了包含分隔符的字符串,此方法将不起作用,因为它会忽略引号。例如,像这样的行:1,10.2,“foo,bar”,abc
将中断,因为foo
和bar
之间的逗号被解释为分隔符。我得到了以下错误:parserror:saw32,第14行应该有31个字段。错误可能是由于在使用多字符分隔符时忽略了引号。
@Gabriel只需执行read\u csv
,而不使用sep
将文件读入pandas数据帧?是的,它将读取文件,但不会去除空白(这是OP的重点)。这里发布的其他解决方案之一将需要做到这一点。@Gabriel它仍然可以用正则表达式完成,但要用更复杂的表达式。我知道,尽管我对正则表达式不够精通,无法构造它!但问题是,我的csv文件的复杂正则表达式可能无法用于其他输入。这就是为什么我不认为这个解决方案像那些在加载步骤后去掉空白的解决方案那样优雅。处理数据帧的函数非常方便。记住返回对象,df=df\u strip(df)