2017-02-17 149 views
0

我试图简化熊猫和python的语法,当执行一个基本的熊猫操作。熊猫比较

我有4列:

  • A_ID
  • a_score
  • B_ID
  • b_score

我创建了一个新的标签称为基于以下DOC_TYPE

  • 一个> = B,DOC_TYPE:一个
  • B> A,DOC_TYPE:乙

林在如何在大熊猫其中存在,但b计算挣扎不,在这个那么情况就需要成为标签。现在它返回else语句或b。 我需要创建2个额外的比较,其规模可能是有效的,因为我已经比较过之前的数据。寻找如何改进它。

df = pd.DataFrame({ 
     'a_id': ['A', 'B', 'C', 'D', '', 'F', 'G'], 
     'a_score': [1, 2, 3, 4, '', 6, 7], 
     'b_id': ['a', 'b', 'c', 'd', 'e', 'f', ''], 
     'b_score': [0.1, 0.2, 3.1, 4.1, 5, 5.99, None], 

    }) 
    print df 
    # Replace empty string with NaN 
    m_score = r['a_score'] >= r['b_score'] 
    m_doc = (r['a_id'].isnull() & r['b_id'].isnull()) 
    df = df.apply(lambda x: x.str.strip() if isinstance(x, str) else x).replace('', np.nan) 
    # Calculate higher score 
    df['doc_id'] = df.apply(lambda df: df['a_id'] if df['a_score'] >= df['b_score'] else df['b_id'], axis=1) 
    # Select type based on higher score 
    r['doc_type'] = numpy.where(m_score, 'a', 
          numpy.where(m_doc, numpy.nan, 'b'))  

    # Additional lines looking for improvement: 
    df['doc_type'].loc[(df['a_id'].isnull() & df['b_id'].notnull())] = 'b' 
    df['doc_type'].loc[(df['a_id'].notnull() & df['b_id'].isnull())] = 'a' 
    print df 
+0

你需要在现实中DOC_ID?或者它只是你的处理代码的一部分? – Psidom

+0

只是处理代码的一部分,我们现在可以忽略它。 – spicyramen

回答

1

使用numpy.where,假设你的逻辑是:

  • 都存在,则DOC_TYPE将成为一个具有更高的分数;
  • 一个缺少,doc_type将是一个不为空;
  • 两者都缺失,doc_type将为空;

增加了额外的优势情况下,在最后一行:

import numpy as np 

df = df.replace('', np.nan) 
df['doc_type'] = np.where(df.b_id.isnull() | (df.a_score >= df.b_score), 
          np.where(df.a_id.isnull(), None, 'a'), 'b') 
df 

enter image description here

0

使用申请方法在大熊猫与自定义功能,在您的数据帧尝试:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({ 
     'a_id': ['A', 'B', 'C', 'D', '', 'F', 'G'], 
     'a_score': [1, 2, 3, 4, '', 6, 7], 
     'b_id': ['a', 'b', 'c', 'd', 'e', 'f', ''], 
     'b_score': [0.1, 0.2, 3.1, 4.1, 5, 5.99, None], 

    }) 

df = df.replace('',np.NaN) 

def func(row): 
    if np.isnan(row.a_score) and np.isnan(row.b_score): 
     return np.NaN 
    elif np.isnan(row.b_score) and not(np.isnan(row.a_score)): 
     return 'a' 
    elif not(np.isnan(row.b_score)) and np.isnan(row.a_score): 
     return 'a' 
    elif row.a_score>=row.b_score: 
     return 'a' 
    elif row.b_score>row.a_score: 
     return 'b' 

df['doc_type'] = df.apply(func,axis=1) 

可以使功能复杂,因为你需要和包括比较任何量和添加更多如果您需要,可以稍后再处理。

+0

嗨Gaurav,第7行(索引6)你的逻辑不起作用,它返回None,它应该返回'a',因为有一个值为a_id和a_score。上面描述的是同样的问题。 – spicyramen

0

不确定我是否完全理解所有条件或者是否存在任何特定的边界情况,但我认为只需在列上执行np.argmax并在完成时交换'a'或'b'的值:

In [21]: import numpy as np 

In [22]: df['doc_type'] = pd.Series(np.argmax(df[["a_score", "b_score"]].values, axis=1)).replace({0: 'a', 1: 'b'}) 

In [23]: df 
Out[23]: 
    a_id a_score b_id b_score doc_type 
0 A  1 a  0.10  a 
1 B  2 b  0.20  a 
2 C  3 c  3.10  b 
3 D  4 d  4.10  b 
4   2 e  5.00  b 
5 F   f  5.99  a 
6 G  7   NaN  a