尝试学习熊猫,我将其应用到使用标准python / php工具通过各种循环解决的问题上。 说我有两个这样的数据帧,df1小于df2,对于df2中的ClientApplication值,df1中可能没有对应的子程序
df1
ClientApplication Subprogram
insert_data AA1
remove_data AB1
update_data XX0
df2
Time ClientApplication Duration Result
2020-01-01 insert_data 300 error
2020-02-01 insert_data 100 ok
2020-03-01 update_data 1000 ok
2020-06-02 remove_data 50 error
2020-07-01 check_data 0 ok
我需要实现一些目标:
为df2中的子程序添加一列,其值对应 到df1中的同一ClientApplication。当没有 df1中找到的对应项添加任意值(“未知”)
使用子程序在df1中添加缺少的ClienApplication值 值设置为任意值“未知”
我可以使用on条件通过合并获得想要的东西,我知道我也可以通过映射来实现,但是我找不到通过添加任意字符串'Unknown'来管理缺失值的方法那时除了基于NaN值进行其他操作之外,那么我看不出在熊猫中实现这一目标的最紧凑,最有效的方法。
df1是一个小的数据帧,少于1000行,而df2则为数百万。
df1是通过sql查询构造的,而df2是从csv构造的,由于csv包含所有新标识的Unknown ClientApplication,因此df1表将需要更新,并且df2将与添加的列一起导入到db中和更新的值,这与任务无关,但是可能会影响选择最有效的方法吗?
答案 0 :(得分:0)
如果我理解正确,首先让我们创建数据框:
from io import StringIO
content = """ClientApplication Subprogram
insert_data AA1
remove_data AB1
update_data XX0
"""
df1 = pd.read_csv(StringIO(content), sep=" ")
print(df1)
ClientApplication Subprogram
0 insert_data AA1
1 remove_data AB1
2 update_data XX0
content = """Time ClientApplication Duration Result
2020-01-01 insert_data 300 error
2020-02-01 insert_data 100 ok
2020-03-01 update_data 1000 ok
2020-06-02 remove_data 50 error
2020-07-01 check_data 0 ok
"""
df2 = pd.read_csv(StringIO(content), sep=" ")
print(df2)
Time ClientApplication Duration Result
0 2020-01-01 insert_data 300 error
1 2020-02-01 insert_data 100 ok
2 2020-03-01 update_data 1000 ok
3 2020-06-02 remove_data 50 error
4 2020-07-01 check_data 0 ok
好,现在合并:
result = pd.merge(df1, df2, how='right', on='ClientApplication', )
result
ClientApplication Subprogram Time Duration Result
0 insert_data AA1 2020-01-01 300 error
1 insert_data AA1 2020-02-01 100 ok
2 remove_data AB1 2020-06-02 50 error
3 update_data XX0 2020-03-01 1000 ok
4 check_data NaN 2020-07-01 0 ok
,现在您可以使用 .fillna()来“设置为任意值'Unknown'”
result.fillna("Unknown")
ClientApplication Subprogram Time Duration Result
0 insert_data AA1 2020-01-01 300 error
1 insert_data AA1 2020-02-01 100 ok
2 remove_data AB1 2020-06-02 50 error
3 update_data XX0 2020-03-01 1000 ok
4 check_data Unknown 2020-07-01 0 ok
答案 1 :(得分:0)
要在df2中创建新列,请将map
与fillna
一起使用
s = df1.set_index('ClientApplication')['Subprogram']
df2['Subprogram'] = df2['ClientApplication'].map(s).fillna('Unknown')
#result df2
Time ClientApplication Duration Result Subprogram
0 2020-01-01 insert_data 300 error AA1
1 2020-02-01 insert_data 100 ok AA1
2 2020-03-01 update_data 1000 ok XX0
3 2020-06-02 remove_data 50 error AB1
4 2020-07-01 check_data 0 ok Unknown
我发现在df1中添加新值的最简单方法是在df2中使用drop_duplicates
重做df1(我相信它比merge
更快,也许您可以测试以证明?!:- )
df1 = df2[['ClientApplication', 'Subprogram']].drop_duplicates()
#result df1
ClientApplication Subprogram
0 insert_data AA1
2 update_data XX0
3 remove_data AB1
4 check_data Unknown