我有一个 CSV 文件,每天都会根据从网站上抓取的一些数据进行更新。该文件的格式并不理想,但不幸的是还有其他依赖项导致它,所以我无法更改数字的格式化方式。我每天都会阅读已有的 CSV,然后在信息出现时使用每天的数据进行更新。该文件的格式如下:
2015-06-29| | 2015-06-28| | 2015-06-27| ...
col1 | col2 | col1 | col2 | col1 | col2
10 | 3 | 103.4 | 6.6 | 103.2 | 4.3
1028 | 5 | 102.4 | 6.2 | 103.3 | 2.2
90 | 6 | 91.7 | 5.0 | 93.1 | 2.4
105 | 1 | 100.8 | 5.5 | 100.9 | 1.7
345 | 7 | 103.0 | 6.1 | 102.9 | 6.3
53 | 3 | 106.0 | 8.6 | 105.3 | 7.6
110 | 5 | 113.0 | 9.1 | 110.9 | 6.7
32 | 4 | 3.9 | 1.8 | 3.5 | 2.9
...
Run Code Online (Sandbox Code Playgroud)
当新的一天到来时,我会将以下内容保存在单独的 Pandas 数据框中:
2015-06-30|
col1 | col2
1 | 3
28 | 5
901 | 6
15 | 1
45 | 7
533 | 3
15 | 5
75 | 4
Run Code Online (Sandbox Code Playgroud)
我只是尝试将这两行插入到最新条目的左侧,然后保存到上一个文件。我对此没有遇到任何问题,但我在日期旁边的列中收到“未命名:#”,而不是像这样的空单元格:
2015-06-29| | 2015-06-28| unnamed:0 | 2015-06-27| unnamed:1
col1 | col2 | col1 | col2 | col1 | col2
10 | 3 | 103.4 | 6.6 | 103.2 | 4.3
1028 | 5 | 102.4 | 6.2 | 103.3 | 2.2
90 | 6 | 91.7 | 5.0 | 93.1 | 2.4
105 | 1 | 100.8 | 5.5 | 100.9 | 1.7
345 | 7 | 103.0 | 6.1 | 102.9 | 6.3
53 | 3 | 106.0 | 8.6 | 105.3 | 7.6
110 | 5 | 113.0 | 9.1 | 110.9 | 6.7
32 | 4 | 3.9 | 1.8 | 3.5 | 2.9
Run Code Online (Sandbox Code Playgroud)
如何删除这些单元格值并保留空单元格?
如果您使用 读取 CSV, header=None
则空单元格将填充NaN
, 而不是"Unnamed:X"
:
df = pd.read_table('data', sep='\s*[|]\s*', header=None)
# 0 1 2 3 4 5
# 0 2015-06-29 NaN 2015-06-28 NaN 2015-06-27 NaN
# 1 col1 col2 col1 col2 col1 col2
# 2 10 3 103.4 6.6 103.2 4.3
# ...
Run Code Online (Sandbox Code Playgroud)
然后,您可以从数据帧的其余部分中分割前两行:
columns = df.iloc[:2]
df = df.iloc[2:]
Run Code Online (Sandbox Code Playgroud)
NaN
通过调用将 s替换为空字符串fillna
,
columns = columns.fillna('')
Run Code Online (Sandbox Code Playgroud)
然后将列设为 MultiIndex:
columns = pd.MultiIndex.from_arrays(columns.values.tolist())
df.columns = columns
Run Code Online (Sandbox Code Playgroud)
例如,如果data
有内容
2015-06-29| | 2015-06-28| | 2015-06-27|
col1 | col2 | col1 | col2 | col1 | col2
10 | 3 | 103.4 | 6.6 | 103.2 | 4.3
1028 | 5 | 102.4 | 6.2 | 103.3 | 2.2
90 | 6 | 91.7 | 5.0 | 93.1 | 2.4
105 | 1 | 100.8 | 5.5 | 100.9 | 1.7
345 | 7 | 103.0 | 6.1 | 102.9 | 6.3
53 | 3 | 106.0 | 8.6 | 105.3 | 7.6
110 | 5 | 113.0 | 9.1 | 110.9 | 6.7
32 | 4 | 3.9 | 1.8 | 3.5 | 2.9
Run Code Online (Sandbox Code Playgroud)
并data2
有内容
2015-06-30|
col1 | col2
1 | 3
28 | 5
901 | 6
15 | 1
45 | 7
533 | 3
15 | 5
75 | 4
Run Code Online (Sandbox Code Playgroud)
然后
import pandas as pd
def read_multiheader(filepath_or_buffer, num_header_rows=2, encoding=None):
from pandas.io.common import get_filepath_or_buffer
filepath_or_buffer, _ = get_filepath_or_buffer(filepath_or_buffer, encoding)
df = pd.read_table(filepath_or_buffer, sep='\s*[|]\s*', header=None)
columns = df.iloc[:num_header_rows]
columns = columns.fillna('')
columns = pd.MultiIndex.from_arrays(columns.values.tolist())
df = df.iloc[num_header_rows:]
df.columns = columns
return df
df = read_multiheader('data')
df2 = read_multiheader('data2')
newdf = pd.concat([df2, df], axis=1)
print(newdf)
Run Code Online (Sandbox Code Playgroud)
产量
2015-06-30 2015-06-29 2015-06-28 2015-06-27
col1 col2 col1 col2 col1 col2 col1 col2
2 1 3 10 3 103.4 6.6 103.2 4.3
3 28 5 1028 5 102.4 6.2 103.3 2.2
4 901 6 90 6 91.7 5.0 93.1 2.4
5 15 1 105 1 100.8 5.5 100.9 1.7
6 45 7 345 7 103.0 6.1 102.9 6.3
7 533 3 53 3 106.0 8.6 105.3 7.6
8 15 5 110 5 113.0 9.1 110.9 6.7
9 75 4 32 4 3.9 1.8 3.5 2.9
Run Code Online (Sandbox Code Playgroud)