2016-11-28 62 views
0

我在python 3.熊猫数据帧的基础上,其他行

一个熊猫数据帧在该数据帧有具有两列(这可以是全部),I”相同值的行的选择分配值我会把这称为一个组。 每行在列中也有一个值为True/False

现在的每一行我想,要知道,如果其组中的任何行的False值,如果是这样,我想在另一列该组中分配False值的每一行。我已经成功地做到这一点在for循环,但它是相当缓慢:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({'E': [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], 
        'D': [0, 1, 2, 3, 4, 5, 6], 
        'C': [True, True, False, False, True, True, True], 
        'B': ['aa', 'aa', 'aa', 'bb', 'cc', 'dd', 'dd'], 
        'A': [0, 0, 0, 0, 1, 1, 1]}) 

其中给出:

df: 
    A B  C D E 
    0 0 aa True 0 NaN 
    1 0 aa True 1 NaN 
    2 0 aa False 2 NaN 
    3 0 bb False 3 NaN 
    4 1 cc True 4 NaN 
    5 1 dd True 5 NaN 
    6 1 dd True 6 NaN 

现在我运行的循环:

for i in df.index: 
    df.ix[i, 'E'] = df[(df['A'] == df.iloc[i]['A']) & (df['B'] == df.iloc[i]['B'])]['C'].all() 

然后给出期望的结果:

df: 
    A B  C D  E 
    0 0 aa True 0 False 
    1 0 aa True 1 False 
    2 0 aa False 2 False 
    3 0 bb False 3 False 
    4 1 cc True 4 True 
    5 1 dd True 5 True 
    6 1 dd True 6 True 

W母鸡运行这为我的整个DataFrame约100万行,这需要年龄。所以,看使用.apply()避免for循环我经历了以下问题跌跌撞撞:apply a function to a pandas Dataframe whose retuned value is based on other rows

然而

def f(x): return False not in x 
df.groupby(['A','B']).C.apply(f) 

回报:

A B 
0 aa False 
    bb  True 
1 cc  True 
    dd  True 

有谁知道一个更好的办法或如何解决最后一种情况?

回答

1

您可以尝试使用pd.merge进行SQL式连接。

执行与您正在做的相同的组,但将min()应用于它以查找任何具有C == True的情况。然后将其转换为DataFrame,将该列重命名为“E”,然后将其合并回df。

df = pd.DataFrame({'D': [0, 1, 2, 3, 4, 5, 6], 
       'C': [True, True, False, False, True, True, True], 
       'B': ['aa', 'aa', 'aa', 'bb', 'cc', 'dd', 'dd'], 
       'A': [0, 0, 0, 0, 1, 1, 1]}) 

falses = pd.DataFrame(df.groupby(['A', 'B']).C.min() == True) 
falses = falses.rename(columns={'C': 'E'}) 

df = df.merge(falses, left_on=['A', 'B'], right_index=True) 
+0

伟大而快速的工程!然而,'... C.min()== False'应该检查'True'而不是 – Swier

+0

啊,很好!我编辑过。 – cggarvey