我的数据框有 3 列:
File-Name
Time Stamp
File Size
读取会添加文件名太长的行。对于每次出现这种情况,我需要:
这里有第 20 行和第 21 行。第 21 行是文件路径和名称的多余部分:
20 ./.c9/dependencies/extensionHost/956a43f1ecc7f34424174768925cd9cc5a3e006d2ad71e6bd939f2a 2024-04-17 12:56 135268
21 None NaN e04e9ef74933c4cab24ec0f62a973d0b06e59e466286a73382db011071887b5eafad4b8b9/package
它应该是这样的,并且再次为第 74 行生成了另一个额外行:
70 ./.nvm/versions/node/v20.12.0/include/node/ope... 2024-03-26 16:18 53440
71 ./.cache/node-gyp/18.19.0/include/node/openssl... 2024-03-06 19:24 53440
72 ./.nvm/versions/node/v20.11.1/include/node/ope... 2024-02-13 23:50 53440
73 ./.c9/node/include/node/openssl/archs 2023-11-29 14:59 53440
74 ./.c9/dependencies/node18-linux-x64/7e2ea6e5ed... 2023-11-29 14:59 53440
75 None NaN 85de0311e77fec00f3ce2303de1affbe390e7b22b96402...
我正在尝试使用合并或组合所有具有 NaN 值的行。
选项 1(始终只有 one 尾随错误行)
import pandas as pd
import numpy as np
data = {'file_name': {0: 'file', 1: None, 2: 'file2', 3: 'file', 4: None},
'timestamp': {0: '2024-01-01 00:00:00', 1: np.nan, 2: '2024-01-01 00:00:00',
3: '2024-01-01 00:00:00', 4: np.nan},
'size': {0: 1, 1: '1_too_long', 2: 2, 3: 3, 4: '3_too_long'}
}
df = pd.DataFrame(data)
df
file_name timestamp size
0 file 2024-01-01 00:00:00 1
1 None NaN 1_too_long
2 file2 2024-01-01 00:00:00 2
3 file 2024-01-01 00:00:00 3
4 None NaN 3_too_long
代码
out = (
df.assign(file_name=(df['file_name'] + (df['size']
.where(df['file_name'].isna())
.shift(-1)
.fillna(''))
)
)
.dropna(subset='file_name')
.reset_index(drop=True)
)
输出
file_name timestamp size
0 file1_too_long 2024-01-01 00:00:00 1
1 file2 2024-01-01 00:00:00 2
2 file3_too_long 2024-01-01 00:00:00 3
解释
Series.where
使用 df['size']
,对 Series.isna
检查条件 df['file_name']
,然后将 Series.shift
与
-1
一起应用,将需要添加到
df['file_name']
Series.fillna
将
NaN
值转换为空字符串 (
''
),添加到
df['file_name']
并通过 df.assign
现在,删除
None
上的 df.dropna
行,以及
subset='file_name'
以获得新的连续索引。
选项 2(可能存在多个尾随错误行)
如果文件名太长以致有多个尾随行,选项 1 将无法按预期工作。在这种情况下,我们可以使用样品
df.groupby
代码
data2 = {'file_name': {0: 'file', 1: None, 2: 'file2', 3: 'file', 4: None, 5: None},
'timestamp': {0: '2024-01-01 00:00:00', 1: np.nan, 2: '2024-01-01 00:00:00',
3: '2024-01-01 00:00:00', 4: np.nan, 5: np.nan},
'size': {0: 1, 1: '1_too_long', 2: 2, 3: 3, 4: '3_way', 5: '_too_long'}
}
df2 = pd.DataFrame(data2)
df2
file_name timestamp size
0 file 2024-01-01 00:00:00 1
1 None NaN 1_too_long
2 file2 2024-01-01 00:00:00 2
3 file 2024-01-01 00:00:00 3
4 None NaN 3_way # multiple rows
5 None NaN _too_long # multiple rows
输出
gr = df2['file_name'].notna().cumsum()
out2 = (
df2.assign(file_name=df2['file_name'].where(df2['file_name'].notna(),
df2['size'])
)
.groupby(gr, as_index=False)
.agg({'file_name': lambda x: ''.join(x),
'timestamp': 'first',
'size': 'first'})
)
解释
file_name timestamp size
0 file1_too_long 2024-01-01 00:00:00 1
1 file2 2024-01-01 00:00:00 2
2 file3_way_too_long 2024-01-01 00:00:00 3
和 Series.notna
对属于一个文件名的行进行分组。
Series.cumsum
上使用
Series.where
:如果
df2['file_name']
则保留值,否则获得
notna
并通过
df2['size']
覆盖原始 'file_name' 列。
assign
,通过我们的小组(
df.groupby
),然后申请
gr
。对于“file_name”,我们需要一个 groupby.agg
。对于“时间戳”和“大小”,只需获取 join
。