2017-10-23 4 views
1

데이터 프레임 열의 각 행에서 하위 문자열을 검색하고 싶습니다. 어딘가에 열이 집합으로 변환 될 수 있는지 검색하는 것이 더 빠릅니다. 여기에 제안 된 접근 방식을 사용하려고합니다 : How to convert list into set in pandas? 하지만 예상치 못한 결과가 나타납니다. 나는 다음과 같은 접근 방식 사용하면목록을 팬더 데이터 프레임 세트로 변환

 R_id  Badges 
0 7LBCS  New Reviewer - 1 Review 
1 8FKME  New Reviewer - 1 Review; New Photographer - 1 Photo; Reviewer - 3 Reviews; 

가 :

df['Badges'] = df.apply(lambda row: set(row['Badges']), axis=1) 

또는

df['Badges'] = df['Badges'].apply(set) 

을 나는 위의 dataframe의 각 행에 대해 얻을 출력이 세트입니다 내 dataframe은 다음과 같습니다 행에있는 문자열의 고유 한 문자가 있습니다. 어떤 이유로 출력이 생성되는 즉시 Spyder IDE가 충돌하기 때문에 정확한 출력을 복제 할 수 없습니다. 하지만 첫 번째 행의 출력은 다음과 같습니다.

{'1', '-', 'N', 'e', 'w', 'R', 'v', 'i', 'r'} 

변환으로 변환 할 때 무엇이 ​​잘못 될 수 있습니까?

+0

찾고있는 하위 문자열은 무엇입니까? – GiantsLoveDeathMetal

+0

@GiantsLoveDeathMetal 예를 들어, "새로운 리뷰 작성자"를 찾고 있습니다. 실제 용도로 약 50 개의 부분 문자열을 검색해야합니다. 어떤 행에는 "New Reviewer", "Reviewer", "New Photographer"등과 같은 약 400 개의 서술자가 있습니다. – Rnovice

+0

NIT :'set'으로 변환하면 중복 된 인스턴스가 제거됩니다. – GiantsLoveDeathMetal

답변

2

귀하의 데이터로 작업하기 쉽게 만드는 형식이 아닙니다. Andy의 코드 확장을 권하고 싶습니다. 각 항목마다 고유 한 행이 생성되므로 데이터를 훨씬 효율적으로 필터링 할 수 있습니다.

str.split으로 시작한 다음 str.extract을 사용하여 키 - 값 쌍을 추출하십시오.

df = df.set_index('R_id')\ 
     .Badges.str.split('\s*;\s*', expand=True)\ 
     .stack().reset_index(level=1, drop=1)\ 
     .str.extract('(?P<Name>[^-]+).*(?P<Val>\d+)', expand=True)\ 
     .dropna() 

print(df) 
        Name Val 
R_id       
7LBCS  New Reviewer 1 
8FKME  New Reviewer 1 
8FKME New Photographer 1 
8FKME   Reviewer 3 

한 시간의 고통은 한 세기의 이득이 될 수 있습니다.

+0

코드가하는 일을 완전히 이해하지는 못했지만 결과를보고 나면이 제안이 내 목표를 달성하는 데 더 도움이된다고 생각합니다. 하지만 두 가지 질문이 있습니다. R_id를 인덱스로 설정하지 않고도이 작업을 수행 할 수 있습니까? 그런 식으로 나중에 R_id 열을 사용하여 정렬 작업을 수행 할 수 있습니다. 또한 Val 필드는 현재 설명 뒤에 한 자리 만 캡쳐하고 있습니다. 어떤 경우에는 Expert Reviewer - 110 Reviews와 같은 것을 가지고 있습니다. 위의 코드를 단지 1 대신 110을 캡처하도록 어떻게 변경합니까? – Rnovice

+0

또한 왜 다음을 사용하여 새 df의 행을 필터링 할 수 없습니까? df [df.Name == "New Reviewer"]. 이 명령은 빈 데이터 프레임을 반환합니다. – Rnovice

+0

@Rnovice 예 및 예. 첫 번째 질문에 대해서는 df = df.reset_index()를 호출하십시오. name 열의 경우 df.Name = df.Name.str.strip()을 사용하면 후행 공백이 있고 필터링이 이후에 작동해야한다고 생각합니다. –

2

당신은 당신이 설정 사용하기 전에 분리해야 다음과 같이

In [11]: df.Badges.str.split('\s*;\s*').apply(set) 
Out[11]: 
0       {New Reviewer - 1 Review} 
1 {Reviewer - 3 Reviews, , New Photographer - 1 ... 
Name: Badges, dtype: object 

내가 그것을 조정할 수있는 빈 병을 던져하려면

In [12]: df.Badges.str.split('\s*;\s*').apply(lambda bs: set(b for b in bs if b)) 
Out[12]: 
0       {New Reviewer - 1 Review} 
1 {Reviewer - 3 Reviews, New Photographer - 1 Ph... 
Name: Badges, dtype: object 

을하거나 스트립 수있는 ';' 첫 번째 (즉 유일한 장소가 비어있는 경우에서 유래) :

In [13]: df.Badges.str.strip(';').str.split('\s*;\s*').apply(set) 
Out[13]: 
0       {New Reviewer - 1 Review} 
1 {Reviewer - 3 Reviews, New Photographer - 1 Ph... 
Name: Badges, dtype: object 

후자는 약간 더 효율적일 수 있습니다 ...