使用 pandas.read_csv 导入有空格的文本数据
import text data having spaces using pandas.read_csv
我想使用 pandas.read_csv:
导入文本文件
1541783101 8901951488 file.log 12345 123456
1541783401 21872967680 other file.log 23456 123
1541783701 3 third file.log 23456 123
这里的难点在于,列被一个或多个 spaces 分隔,但是有一列包含具有 spaces 的文件名。所以我不能使用 sep=r"\s+"
来识别列,因为在第一个具有 space 的文件名处会失败。文件格式没有固定的列宽。
但是每个文件名都以“.log”结尾。我可以编写单独的正则表达式来匹配每一列。是否可以使用这些来识别要导入的列?或者是否可以编写一个分隔符正则表达式来选择所有不匹配任何匹配正则表达式的列的字符?
更新问题的答案 -
这是无论数据宽度如何都不会失败的代码。您可以根据自己的需要进行修改。
df = pd.read_table('file.txt', header=None)
# Replacing uneven spaces with single space
df = df[0].apply(lambda x: ' '.join(x.split()))
# An empty dataframe to hold the output
out = pd.DataFrame(np.NaN, index=df.index, columns=['col1', 'col2', 'col3', 'col4', 'col5'])
n_cols = 5 # number of columns
for i in range(n_cols-2):
# 0 1
if i == 0 or i == 1:
out.iloc[:, i] = df.str.partition(' ').iloc[:,0]
df = df.str.partition(' ').iloc[:,2]
else:
out.iloc[:, 4] = df.str.rpartition(' ').iloc[:,2]
df = df.str.rpartition(' ').iloc[:,0]
out.iloc[:,3] = df.str.rpartition(' ').iloc[:,2]
out.iloc[:,2] = df.str.rpartition(' ').iloc[:,0]
print(out)
+---+------------+-------------+----------------+-------+--------+
| | col1 | col2 | col3 | col4 | col5 |
+---+------------+-------------+----------------+-------+--------+
| 0 | 1541783101 | 8901951488 | file.log | 12345 | 123456 |
| 1 | 1541783401 | 21872967680 | other file.log | 23456 | 123 |
| 2 | 1541783701 | 3 | third file.log | 23456 | 123 |
+---+------------+-------------+----------------+-------+--------+
注意 - 代码被硬编码为 5 列。也可以泛化。
上一个答案-
使用pd.read_fwf()
读取固定宽度的文件。
你的情况:
pd.read_fwf('file.txt', header=None)
+---+----------+-----+-------------------+-------+--------+
| | 0 | 1 | 2 | 3 | 4 |
+---+----------+-----+-------------------+-------+--------+
| 0 | 20181201 | 3 | file.log | 12345 | 123456 |
| 1 | 20181201 | 12 | otherfile.log | 23456 | 123 |
| 2 | 20181201 | 200 | odd file name.log | 23456 | 123 |
+---+----------+-----+-------------------+-------+--------+
我想使用 pandas.read_csv:
导入文本文件1541783101 8901951488 file.log 12345 123456
1541783401 21872967680 other file.log 23456 123
1541783701 3 third file.log 23456 123
这里的难点在于,列被一个或多个 spaces 分隔,但是有一列包含具有 spaces 的文件名。所以我不能使用 sep=r"\s+"
来识别列,因为在第一个具有 space 的文件名处会失败。文件格式没有固定的列宽。
但是每个文件名都以“.log”结尾。我可以编写单独的正则表达式来匹配每一列。是否可以使用这些来识别要导入的列?或者是否可以编写一个分隔符正则表达式来选择所有不匹配任何匹配正则表达式的列的字符?
更新问题的答案 -
这是无论数据宽度如何都不会失败的代码。您可以根据自己的需要进行修改。
df = pd.read_table('file.txt', header=None)
# Replacing uneven spaces with single space
df = df[0].apply(lambda x: ' '.join(x.split()))
# An empty dataframe to hold the output
out = pd.DataFrame(np.NaN, index=df.index, columns=['col1', 'col2', 'col3', 'col4', 'col5'])
n_cols = 5 # number of columns
for i in range(n_cols-2):
# 0 1
if i == 0 or i == 1:
out.iloc[:, i] = df.str.partition(' ').iloc[:,0]
df = df.str.partition(' ').iloc[:,2]
else:
out.iloc[:, 4] = df.str.rpartition(' ').iloc[:,2]
df = df.str.rpartition(' ').iloc[:,0]
out.iloc[:,3] = df.str.rpartition(' ').iloc[:,2]
out.iloc[:,2] = df.str.rpartition(' ').iloc[:,0]
print(out)
+---+------------+-------------+----------------+-------+--------+
| | col1 | col2 | col3 | col4 | col5 |
+---+------------+-------------+----------------+-------+--------+
| 0 | 1541783101 | 8901951488 | file.log | 12345 | 123456 |
| 1 | 1541783401 | 21872967680 | other file.log | 23456 | 123 |
| 2 | 1541783701 | 3 | third file.log | 23456 | 123 |
+---+------------+-------------+----------------+-------+--------+
注意 - 代码被硬编码为 5 列。也可以泛化。
上一个答案-
使用pd.read_fwf()
读取固定宽度的文件。
你的情况:
pd.read_fwf('file.txt', header=None)
+---+----------+-----+-------------------+-------+--------+
| | 0 | 1 | 2 | 3 | 4 |
+---+----------+-----+-------------------+-------+--------+
| 0 | 20181201 | 3 | file.log | 12345 | 123456 |
| 1 | 20181201 | 12 | otherfile.log | 23456 | 123 |
| 2 | 20181201 | 200 | odd file name.log | 23456 | 123 |
+---+----------+-----+-------------------+-------+--------+