【发布时间】:2022-06-24 23:41:02
【问题描述】:
到目前为止,我还没有对 Pandas 做任何繁重的工作,现在我有点情况,可以使用一些指导。
我有一些代码可以生成以下数据框:
ID_x HOST_NM IP_ADDRESS_x SERIAL_x ID_y IP_ADDRESS_y COST PURCHASE_DATE ID IP_ADDRESS SERIAL_y OS
0 62bf philip 192.168.1.115 12345 32 192.168.1.115 36.78 2018-05-05 2 192.168.1.115 NaN Debian 11 Linux
1 3a73 vic 192.168.1.145 17B0P 33 192.168.1.145 749.64 2018-07-26 3 192.168.1.145 17B0P DSM 7.1-42661
2 4237 BILL 192.168.1.99 NaN 31 192.168.1.99 3584.83 2018-03-15 1 192.168.1.99 38174 Windows 10 LTSC
3 3027 tim 192.168.1.96 C02G7 34 192.168.1.96 1289.00 2021-10-13 4 192.168.1.100 C02G7 macOS Monterey 12.4
此数据帧是通过其他三个数据帧的外部合并生成的。重复数据是有意的。如果我们在该行上有主机名和一致的 IP 地址,我们的想法是填写缺失的序列号;我想连续获取所有 IP 地址,如果它们 80% 一致,则使用该地址,否则使用 NaN。
然后在稍后阶段,我将删除多余的列。
这是一个 PoC。以上是一个小的示例数据集,但实际数据集包含大约 35K 个唯一设备(行)和 112 列(4 组冗余数据)。
我没有在 Pandas 中看到任何看起来像是为这种情况量身定制的东西。这有什么不对吗?
更多示例和此处使用的代码可以在 github here 上找到。
上面引用的代码如下。
import logging
from functools import reduce
# import numpy
import pandas
log = logging.getLogger("merge")
log.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
log.addHandler(ch)
r1 = [
{
'ID': '62bf',
'HOST_NM': 'philip',
'IP_ADDRESS': '192.168.1.115',
'SERIAL': '12345',
},
{
'ID': '3a73',
'HOST_NM': 'vic',
'IP_ADDRESS': '192.168.1.145',
'SERIAL': '17B0P',
},
{
'ID': '4237',
'HOST_NM': 'BILL',
'IP_ADDRESS': '192.168.1.99',
'SERIAL': '',
},
{
'ID': '3027',
'HOST_NM': 'tim',
'IP_ADDRESS': '192.168.1.96',
'SERIAL': 'C02G7',
},
]
r2 = [
{
'ID': '34',
'HOST_NM': 'tim',
'IP_ADDRESS': '192.168.1.96',
'COST': '1289.00',
'PURCHASE_DATE': '2021-10-13',
},
{
'ID': '33',
'HOST_NM': 'vic',
'IP_ADDRESS': '192.168.1.145',
'COST': '749.64',
'PURCHASE_DATE': '2018-07-26',
},
{
'ID': '31',
'HOST_NM': 'BILL',
'IP_ADDRESS': '192.168.1.99',
'COST': '3584.83',
'PURCHASE_DATE': '2018-03-15',
},
{
'ID': '32',
'HOST_NM': 'philip',
'IP_ADDRESS': '192.168.1.115',
'COST': '36.78',
'PURCHASE_DATE': '2018-05-05',
},
]
r3 = [
{
'ID': '2',
'HOST_NM': 'philip',
'IP_ADDRESS': '192.168.1.115',
'SERIAL': '',
'OS': 'Debian 11 Linux',
},
{
'ID': '3',
'HOST_NM': 'vic',
'IP_ADDRESS': '192.168.1.145',
'SERIAL': '17B0P',
'OS': 'DSM 7.1-42661',
},
{
'ID': '1',
'HOST_NM': 'BILL',
'IP_ADDRESS': '192.168.1.99',
'SERIAL': '38174',
'OS': 'Windows 10 LTSC',
},
{
'ID': '4',
'HOST_NM': 'tim',
'IP_ADDRESS': '192.168.1.100',
'SERIAL': 'C02G7',
'OS': 'macOS Monterey 12.4',
},
]
def unique(l: list) -> list:
u = []
for e in l:
if e not in u:
u.append(e)
return list(u)
df1 = pandas.DataFrame(r1)
df2 = pandas.DataFrame(r2)
df3 = pandas.DataFrame(r3)
df_list = [df1, df2, df3]
df_keys = {
0: ["ID", "SERIAL"],
1: ["HOST_NM"],
2: ["HOST_NM", "SERIAL"],
}
target_columns = ["HOST_NM", "SERIAL", "IP_ADDRESS"]
df = reduce(lambda left, right: pandas.merge(
left, right, on=["HOST_NM"], how="outer"), df_list)
log.debug(df)
# Replace null and empty strings with numpy.NaN
# df = df.replace(r"^\s*$", numpy.NaN, regex=True)
df = df.mask(df == '')
log.debug(f'\n\n{df}')
【问题讨论】:
-
您的示例需要最小化且可运行。
records包是什么?我们需要担心日志记录吗?如果没有,它们只是分散注意力。具体来说,您想要的输出是什么? (例如,将其与将生成期望输出的输入数据帧样本一起硬编码到问题中) -
每条记录都是一个字典列表。它们从代码主体中删除并放入 records.py 以保持整洁。然而,我的问题实际上是关于找到一种方法来获得所需的结果,最好不要遍历 df.如果不清楚,请道歉。
-
没有您的数据,任何人都无法运行您的代码。将字典的示例硬编码到示例中,然后输入这些示例的结果。
标签: python pandas dataframe data-quality