【问题标题】:fill NaN with another lookup table用另一个查找表填充 NaN
【发布时间】:2017-01-29 14:58:43
【问题描述】:

有没有办法通过匹配名称、标线和单元格rev 来用test=default 的值填充NaN

在“测试”列中有几个变量:

有没有办法更新其他行的值?因为数据类型“do”的优先级高于 int 并删除“do”数据行?

数据:
测试数据类型名称值标线 cell_rev
默认 int s 0x45 CR1
默认 int s 0xCB CR3
默认do s 0.68 CR1

我想得到:

测试数据类型名称值 reticle cell_rev
默认 int s 0.68 CR1
默认 int s 0xCB CR3

【问题讨论】:

  • 您应该将示例包含为文本,而不是屏幕截图。

标签: python pandas dataframe multiple-columns nan


【解决方案1】:

您可以使用set_indexunstack 进行整形,然后使用ffill 添加缺失值,最后由stack 整形为原始值:

df = df.set_index(['name','value_old','reticle','test','cell_rev'])
       .unstack()
       .ffill()
       .stack()
       .reset_index()

print (df)
  name value_old reticle     test cell_rev value_new
0    s      0x8E     A28  default      CR1      0x8C
1    s      0x8E     A28  default      CR3      0x8E
2    s      0x8E     A28     etlc      CR1      0x8C
3    s      0x8E     A28     etlc      CR3      0x8E

通过评论编辑:

使用由boolean indexing 创建的子集df1 使用merge,然后通过combine_firstfillna 填充NaN 值:

df1 = df.ix[df.test == 'default']
print (df1)     
      test name value_old reticle cell_rev value_new
0  default    s      0x8E     A28      CR1      0x8E
1  default    s      0x8E     A28      CR3      0x8C

df2 = pd.merge(df, df1, how='left', on=['name','reticle','cell_rev'], suffixes=('','1'))
print (df2)
      test name value_old reticle cell_rev value_new    test1 value_old1  \
0  default    s      0x8E     A28      CR1      0x8E  default       0x8E   
1  default    s      0x8E     A28      CR3      0x8C  default       0x8E   
2     etlc    s      0x8E     A28      CR1      0x44  default       0x8E   
3     etlc    s      0x8E     A28      CR3      0x44  default       0x8E   
4      mlc    s      0x1E     A28      CR1       NaN  default       0x8E   
5      mlc    s      0x1E     A28      CR3       NaN  default       0x8E   
6      slc    s      0x2E     A28      CR1       NaN  default       0x8E   
7      slc    s      0x2E     A28      CR3       NaN  default       0x8E   

  value_new1  
0       0x8E  
1       0x8C  
2       0x8E  
3       0x8C  
4       0x8E  
5       0x8C  
6       0x8E  
7       0x8C 
df['value_new'] = df2['value_new'].combine_first(df2['value_new1'])
#df['value_new'] = df2['value_new'].fillna(df2['value_new1'])
print (df)
      test name value_old reticle cell_rev value_new
0  default    s      0x8E     A28      CR1      0x8E
1  default    s      0x8E     A28      CR3      0x8C
2     etlc    s      0x8E     A28      CR1      0x44
3     etlc    s      0x8E     A28      CR3      0x44
4      mlc    s      0x1E     A28      CR1      0x8E
5      mlc    s      0x1E     A28      CR3      0x8C
6      slc    s      0x2E     A28      CR1      0x8E
7      slc    s      0x2E     A28      CR3      0x8C

【讨论】:

  • 此解决方案适用于样本,但在实际数据中,test 列中只有 defaultetlc 的值?
  • 感谢查看,不,在实际数据中,测试列有“default, etlc, Jlc and klc”,对于jlc和klc,如果value_new为NAN,则应填写NAN按默认值并与其他列匹配(名称、标线、单元格、rev)
  • 是的,我有相同的输出。我认为它是否适用于您的真实数据。对不起。
  • 它采用最后观察到的值而不是默认值,我已将结果添加到问题中,我无法附加为文本,因此附加为图像。关于始终获取默认值的任何想法?非常感谢您在这方面的帮助!
  • 另外,value_old 列可能具有“NAN”值,如果发生这种情况,那么我预计 value_old 将采用默认值。
【解决方案2】:
for i in range(len(df)):
    if df.loc[i, 'value_new'] != df.loc[i, 'value_new']:
        df.loc[i, 'value_new'] = df.loc[(df.test == 'default') &
                                        (df.name == df.loc[i, 'name']) &
                                        (df.reticle == df.loc[i, 'reticle']) &
                                        (df.cell_rev == df.loc[i, 'cell_rev']),
                                        'value_new']

我认为有一个更有效的解决方案,但这应该可行。

【讨论】:

    猜你喜欢
    • 2021-01-24
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 2022-07-22
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多