2016-11-28 3 views
0

у меня есть панд DataFrame в Python 3.панды Dataframe, присвоить значение на основе выбора других строк

В этом DataFrame существуют строки, которые имеют одинаковые значения в двух столбцах (это может быть целые разделы), I» Я назову это группой. Каждая строка также имеет значение True/False в столбце.

Теперь для каждой строки, я хочу знать, если любой строк в своей группе имеют значение False, если да, то я хочу, чтобы присвоить False значение каждой строки в этой группе в другой колонке. Я сумел сделать это в течение петли, но это довольно медленно:

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 ~ 1 миллион строк это занимает много времени. Таким образом, глядя на использование .apply(), чтобы избежать для цикла я наткнулся на следующий вопрос: 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

Вы можете попробовать выполнить соединение в стиле SQL с помощью pd.merge.

Выполняйте ту же самую группу, что и вы, но примените к ней 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

Смежные вопросы