当使用pd.read_clipboard时,如何处理列名包含空格的情况?

3

我很长时间以来一直面临这个真正的问题。

考虑以下数据框:

         A         B  THRESHOLD
       NaN       NaN        NaN
 -0.041158 -0.161571   0.329038
  0.238156  0.525878   0.110370
  0.606738  0.854177  -0.095147
  0.200166  0.385453   0.166235

使用pd.read_clipboard很容易进行复制。但是,如果其中一个列名包含空格:

         A         B     Col #3
       NaN       NaN        NaN
 -0.041158 -0.161571   0.329038
  0.238156  0.525878   0.110370
  0.606738  0.854177  -0.095147
  0.200166  0.385453   0.166235

然后,它被读取为这样:
          A         B       Col  #3
0       NaN       NaN       NaN NaN
1 -0.041158 -0.161571  0.329038 NaN
2  0.238156  0.525878  0.110370 NaN
3  0.606738  0.854177 -0.095147 NaN
4  0.200166  0.385453  0.166235 NaN

我该如何防止这种情况发生?

2
我通常做的是确保列之间分隔超过一个空格。这样,我就可以使用类似于 df = pd.read_clipboard(header=0, sep="\s{2,}", engine="python") 的方法。Atom 和 Sublime Text 都允许您在正则表达式中搜索和替换;这应该会有所帮助。 - Abdou
@Abdou 谢谢,那很有道理。 - cs95
2
我一直在想其他人是如何处理这些问题的。感谢你把它转化为一个问题。 - Abdou
2
@Abdou 是的... pd.read_clipboard 是那个每个人都在用但却没人谈论的工具... 哈哈 - cs95
2个回答

4
在这种情况下,我的做法是将所有列之间间隔两个或更多空格,然后使用sep='\s\s+'作为分隔符,这样当我有单个空格的列标题时,例如上面的第三列,它会将其视为一个列。
         A         B     Col #3
       NaN       NaN        NaN
 -0.041158  -0.161571   0.329038
  0.238156   0.525878   0.110370
  0.606738   0.854177  -0.095147
  0.200166   0.385453   0.166235

df = pd.read_clipboard(sep='\s\s+')

您确实会收到这个警告,但是可以忽略它,因为它已经做得很正确了。或者,如果您的强迫症发作,您可以添加engine='python'

C:\Program Files\Anaconda3\lib\site-packages\pandas\io\clipboards.py:63: ParserWarning: 因为 'c' 引擎不支持正则表达式分隔符(分隔符>1个字符且与 '\s+' 不同被解释为正则表达式),所以回退到 'python' 引擎;您可以通过指定 engine='python' 来避免此警告。 return read_table(StringIO(text), sep=sep, **kwargs)

print(df)

          A         B    Col #3
0       NaN       NaN       NaN
1 -0.041158 -0.161571  0.329038
2  0.238156  0.525878  0.110370
3  0.606738  0.854177 -0.095147
4  0.200166  0.385453  0.166235

当你说让它们相隔2个空格时,是指你将其粘贴到记事本中并手动输入这些空格吗? - cs95
1
好的,这与Abdou所说的类似,很有道理。我还有更多问题,将在未来的问题中提出,但这个答案解决了这个问题,所以谢谢。 - cs95
通常情况下,当我看到带有空格的标题或日期时间时,我总是使用sep='\s\s+',因为通常日期和时间之间会有一个空格,这被视为单个列。 - Scott Boston

1
使用reiopd.read_table来证明我在评论中所说的观点,我复制了您在帖子中的确切文本,并应用了第一轮re.sub以去除任何前导空格。然后,我替换了任何一个数字之前的空格——这是独特的情况,因为列名大多是字符串字符——用2个空格代替。完成所有这些操作后,我将结果字符串转换为一个io.StringIO对象,并将其馈送到pd.read_table函数中。这基本上与将文本复制并粘贴到sublime text中,然后在最终复制生成的字符串并将其馈送到pd.read_clipboard之前应用两个搜索和替换操作相同。
以下代码片段说明了这一点:
import pandas as pd
import re
import io


text = """         A         B     Col #3
        NaN       NaN        NaN
  -0.041158 -0.161571   0.329038
   0.238156  0.525878   0.110370
   0.606738  0.854177  -0.095147
   0.200166  0.385453   0.166235"""


with io.StringIO(re.sub("(?<=[0-9]) +", "  ", re.sub("^ +", "", text))) as fs:
    df =  pd.read_table(fs, header=0, sep="\s{2,}",engine='python')


#           A         B    Col #3
# 0       NaN       NaN       NaN
# 1 -0.041158 -0.161571  0.329038
# 2  0.238156  0.525878  0.110370
# 3  0.606738  0.854177 -0.095147
# 4  0.200166  0.385453  0.166235

感谢您提出问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接