2015-02-07 2 views
2

그래서 파이썬에서 팬더를 사용하고 있습니다. 내가 이렇게 보이는 CSV에서 읽고 있어요 :Python : 팬더를 사용하여 열의 내용이 일치하는 csv의 행 이름을 인쇄하십시오.

내가 꿔 무엇
imageName  color1  color2  color3  color4 
img1   Red  Red  Red  Red 
img2   Blue  Green  Red  Blue 
img3   Yellow  Blue  Red  White 
img4   Blue  Blue  Blue  Blue 

은 (이미지 이름) 행 COLOR1, COLOR2, color3 및 color4이 모두 동일한 경우를 인쇄하다 할 수 있습니다. 나는 SQL

에서 작업을 수행하는 경우 는
SELECT: imageName 
FROM: rows 
WHERE: color1 == color2 == color3 == color4 

나에게 내가 팬더 꽤 새로운 해요 및 구문을 해결하기 위해 노력 해왔다을 img1 및 img4

을 줄 것이다 그러나 나는 문제로 계속 실행.

if (df[(df['color1'] == df['color2'] == df['color3'] == df['color4']])] 
    print df['imageName'] 

하지만 아무리 내가 무엇을하려고 오류로 실행되지 해요 :

내가 지금 노력하고있어 있습니다.

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any(), or a.all(). 

을하지만 그 사용하는 위치를 알아 내기 위해 사투를 벌인거야 :

나는군요. 아니면 내가 올바른 방향으로 나아가고 있다면. 미리 감사드립니다!

답변

2

당신은 query를 사용하십시오 similarish - 구문 :

>>> df.query("color1 == color2 == color3 == color4") 
    imageName color1 color2 color3 color4 
0  img1 Red Red Red Red 
3  img4 Blue Blue Blue Blue 
>>> df.query("color1 == color2 == color3 == color4").imageName 
0 img1 
3 img4 
Name: imageName, dtype: object 

을 양자 택일로, 당신은 할 수 인덱스 부울 시리즈 사용 : nuniqueNaN을 무시하기 때문에,이 미묘하게 다르지만

>>> df[df.filter(like="color").apply(pd.Series.nunique, axis=1) == 1] 
    imageName color1 color2 color3 color4 
0  img1 Red Red Red Red 
3  img4 Blue Blue Blue Blue 

을 .

+0

고마워요! 정확히 내가 무엇을 찾고 있었는지 – Johnsonge

2

이것은 벡터화 된 방법을 알아 내려고하는 한 가지 방법입니다. 기본적으로 행을 가져온 다음 함수를 호출하고 함수 이름과 매개 변수 axis=1을 전달하여 행을 적용하는 함수를 정의합니다. color_cols = [col for col in df if 'color' in col]

In [21]: 

def all_equal(x): 
    return x['color1'] == x['color2'] == x['color3'] == x['color4'] 

df[color_cols].apply(all_equal, axis=1) 
Out[21]: 
0  True 
1 False 
2 False 
3  True 
dtype: bool 
In [23]: 

df[df[color_cols].apply(all_equal, axis=1)]['imageName'] 
Out[23]: 
0 img1 
3 img4 
Name: imageName, dtype: object 

가 더 빠른 방법은 마스크를 정의 할 수와 비트 연산자 사용하는 것입니다 : :이 color_cols은 색상의 열 이름 만 목록에 의해 정의된다

In [27]: 
# mask tests if color 1 equals color 2 and color 3 equals color 4 and color 1 equals color 3 if this is true then all must be the same value 
mask = (df['color1'] == df['color2']) & (df['color3'] == df['color4']) & (df1['color1'] == df['color3']) 
mask 
Out[27]: 
0  True 
1 False 
2 False 
3  True 
dtype: bool 
In [28]: 

df[mask]['imageName'] 
Out[28]: 
0 img1 
3 img4 
Name: imageName, dtype: object 

타이밍을

In [29]: 

%timeit df.query("color1 == color2 == color3 == color4").imageName 
100 loops, best of 3: 7.24 ms per loop 
In [30]: 

%timeit df[(df['color1'] == df['color2']) & (df['color3'] == df['color4']) & (df1['color1'] == df['color3'])].imageName 

100 loops, best of 3: 3.22 ms per loop 

eval을 호출하는 다른 방법이 있습니다.

In [39]: 

%timeit df[df.eval("color1 == color2 & color3 == color4 & color1 == color3")].imageName 
100 loops, best of 3: 7.53 ms per loop 

In [40]: 

%timeit df[df[color_cols].apply(all_equal, axis=1)].imageName 
100 loops, best of 3: 2.55 ms per loop 

마스크 방법은이 샘플 데이터 집합에 대한 쿼리 및 평가 방법보다 2 배 빠릅니다. apply 메서드는 실제로 가장 빠른 방법이지만 다른 메서드와 마찬가지로 확장되지 않으므로 본질적으로 각 행을 반복합니다.

+0

입력 속도가 빠르지 않는 한, 마스크 방법이 여전히 느린 것 같습니다. :-) 더 진지하게, 보통'query' 변환 오버 헤드는 배열이 꽤 커질 때까지 이기기 시작하지 않는다는 것을 의미합니다. (이 문제에 대해서,'df'는'query'가 빠르기 전에 1M 행 길이가 필요합니다.) – DSM

+0

@DSM 참으로 이것은 타이핑하기가 번거롭기 때문에'eval'이'query'보다 조금 느리다는 것에 조금 놀랐습니다 – EdChum

관련 문제