【问题标题】:Is there a way to compare and replace data between 2 dataframe in pandas?有没有办法比较和替换熊猫中 2 个数据框之间的数据?
【发布时间】:2021-12-30 09:54:56
【问题描述】:

我想根据不同数据框的范围清理数据。

范围数据看起来像

labs_range= pd.DataFrame({"Lab":['Albumin','Sodium','Potassium'],'low': [2,2,3],
                         'high':[4,5,4]})

    Lab low high
0   Albumin 2   4
1   Sodium  2   5
2   Potassium   3   4

我想清理的数据看起来像:

labs = pd.DataFrame({"Albumin":[1,1,2,1,2,3,4,5],'Calcium':[1,1,2,1,2,3,4,5],'Sodium':[1,1,2,1,2,3,4,5]})



Albumin Calcium Sodium
0   1   1   1
1   1   1   1
2   2   2   2
3   1   1   1
4   2   2   2
5   3   3   3
6   4   4   4
7   5   5   5

我可以通过使用循环来做到这一点,但如果我们的数据很大,那将花费太长时间。

for i in labs_range['Lab']:
    try:
        labs[i] = np.where((labs[i]<labs_range.loc[labs_range['Lab']==str(i),'low'].values[0]) | (labs[i]>labs_range.loc[labs_range['Lab']==str(i),'high'].values[0]),np.nan,labs[i])
    except:
        print(i)

我们从这个循环中得到的结果是正确的,但希望它更有效。

    Albumin Calcium Sodium
0   nan 1   nan
1   nan 1   nan
2   2.00000 2   2.00000
3   nan 1   nan
4   2.00000 2   2.00000
5   3.00000 3   3.00000
6   4.00000 4   4.00000
7   nan 5   5.00000

【问题讨论】:

    标签: python python-3.x pandas numpy


    【解决方案1】:

    您可以使用pd.isin

    labs = pd.DataFrame({"Albumin":[1,1,2,1,2,3,4,5],'Calcium':[1,1,2,1,2,3,4,5],'Sodium':[1,1,2,1,2,3,4,5]})
       Albumin  Calcium  Sodium
    0        1        1       1
    1        1        1       1
    2        2        2       2
    3        1        1       1
    4        2        2       2
    5        3        3       3
    6        4        4       4
    7        5        5       5
    
    cond = labs.isin({'Albumin': range(2, 5),
                      'Calcium': range(2, 6),
                      'Sodimu': range(3, 5)})
    
    labs.where(cond, np.nan)
    
    
       Albumin  Calcium  Sodium
    0      NaN      NaN     NaN
    1      NaN      NaN     NaN
    2      2.0      2.0     NaN
    3      NaN      NaN     NaN
    4      2.0      2.0     NaN
    5      3.0      3.0     3.0
    6      4.0      4.0     4.0
    7      NaN      5.0     NaN
    

    【讨论】:

    • 这实际上也改变了钙的值。范围内不存在钙。我们在那个数据框中有钾而不是钙
    【解决方案2】:

    由于您的列不相交,我们需要找到第一个重叠列

    colmatch = labs.columns.intersection(labs_range.Lab)
    labs_range = labs_range.set_index('Lab').loc[colmatch]
    labs[colmatch] = labs.where(labs.sub(labs_range.low).ge(0) & labs.sub(labs_range.high).le(0))[colmatch]
    labs
    Out[246]: 
       Albumin  Calcium  Sodium
    0      NaN        1     NaN
    1      NaN        1     NaN
    2      2.0        2     2.0
    3      NaN        1     NaN
    4      2.0        2     2.0
    5      3.0        3     3.0
    6      4.0        4     4.0
    7      NaN        5     5.0
    

    【讨论】:

    • 你能解释一下这段代码是如何工作的吗?这似乎有效。
    • @Sam 找到交集列,然后我们使用 panda 中的 sub 得到大于 low 小于 high 的值,并将其他的值屏蔽为 NaN 赋值给它
    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多