我的数据框有 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},
'Time Stamp': {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},
'File Size': {0: 1, 1: '1_too_long', 2: 2, 3: 3, 4: '3_too_long'}
}
df = pd.DataFrame(data)
df
File-Name Time Stamp File 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['File Size']
.where(df['File-Name'].isna())
.shift(-1)
.fillna(''))
)
}
)
.dropna(subset='File-Name')
.reset_index(drop=True)
)
输出
File-Name Time Stamp File 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['File 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'
以获得新的连续索引。
(可能存在多个尾随错误行) 如果文件名太长以致有多个尾随行,选项 1 将无法按预期工作。在这种情况下,我们可以使用
样品
df.groupby
data2 = {'File-Name': {0: 'file', 1: None, 2: 'file2', 3: 'file', 4: None, 5: None},
'Time Stamp': {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},
'File Size': {0: 1, 1: '1_too_long', 2: 2, 3: 3, 4: '3_way', 5: '_too_long'}
}
df2 = pd.DataFrame(data2)
df2
File-Name Time Stamp File 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['File Size'])
}
)
.groupby(gr, as_index=False)
.agg({'File-Name': lambda x: ''.join(x),
'Time Stamp': 'first',
'File Size': 'first'})
)
使用
File-Name Time Stamp File 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['File Size']
覆盖原始“文件名”列。现在,申请assign
df.groupby
),然后申请gr
。对于“文件名”,我们需要一个
groupby.agg
。对于“时间戳”和“文件大小”,只需获取
join
。