2017-12-19 3 views
0

각 열이 날짜, 지역 및 해당 날짜/지역에서 관찰 된 일련의 ID 인 가변 열 너비가있는 CSV 파일이 있습니다. .Python (Pandas?) : 가변 열 너비가있는 CSV 파일의 데이터 집계

데이터는 다음과 같다 :

12/01/2017,Region1,BMW_123,TESLA_332,TESLA_2002 
11/07/2017,Region2,TESLA_332,BMW_123,TESLA_2002,TESLA_99812 
11/19/2017,Region2,BMW_123,TESLA_31 
10/23/2017,Region1,BMW_4,TESLA_3,TESLA_90 
11/02/2017,Region2,TESLA_28,BMW_56,TESLA_22,TESLA_821 
10/14/2017,Region2,BMW_1,BMW_8,BMW_2,TESLA_3,TESLA_4,TESLA_99,TESLA_81,TESLA_56 

내가하려고 :

(1) ID의 모든 분할 그냥 브랜드를 유지, 그래서 "TESLA_12345"그냥 "TESLA"될 것 . 이 부분은 문제가되지 않습니다.

(2) 각 달 - 지역 튜플에 대한 각 브랜드 (예 : 테슬라 또는 BMW)의 실패 횟수를 파악할 수 있도록 월별로 집계합니다.

의 모양은 출력 (형식은 매우 중요하지 않습니다 - 그냥 읽을 수 있어야한다) :

month region BMW TESLA 
10 Region1 1  2 
12 Region1 1  2 
10 Region2 3  5 
11 Region2 3  7 

CSV의 라인 -을 읽는 것이 작업을 수행하는 자연적인 방법처럼 보인다 (BMW : 2, TESLA : 1)와 같은 카운트를 유지하는 월 사전을 포함하는 2 개의 지역을 포함하는 지역 사전을 가지고 있습니다. 그러나 나는 고심하고 있습니다. 중첩 된 dicts를 업데이트하면 훨씬 간단한 솔루션이 있는지 궁금하다. (또는 Pandas가 쉽게 할 수있는 경우 등)

(참고 : 분명히 mont

datetime.strptime(mydate, "%m/%d/%Y").strftime("%m") 

)

+0

https://stackoverflow.com/questions/15242746/handling-variable-number-of-columns-with-pandas -python – maxymoo

+0

어쩌면 스택으로 뭔가를 할 수 있습니다. 'df_stacked = df.set_index ([ 'date', 'region']). stack()' – maxymoo

+0

답장을 보내 주셔서 감사합니다! 고르지 않은 기둥이있는 판다에서 몇 개의 게시물을 발견했습니다. https://stackoverflow.com/questions/15242746/handling-variable-number-of-column-with-pandas-python/15252012 및 https : // stackoverflow.com/questions/40880724/pandas-failing-with-variable-columns 그러나 파이썬은 판다 데이터 프레임을 사용하는 것이이 경우를 다루는 '좋은'방법인지 또는 줄 단위가 더 적합한지를 알만큼 강하지 않습니다 , 특히 왜냐하면 그것은 기존의 정렬 방식과는 다른 정렬 방식이기 때문입니다 (행 전체에 걸쳐 집계하기 전에 행 내부의 개수를 가져와야하기 때문에). – cataclysmic

답변

4

가 여기에 하나의 접근 방식 : 시간을 함께 한 날로부터 추출 할 수 있습니다. 나는 그것을 꽤 부르지 않을 것이다. 그러나 그것은 일을 끝낸다.

  1. 첫 번째 문제는 각 행의 필드 개수가 서로 다른 것입니다. 한 번에 한 줄씩 파일을 읽고 목록에 저장하십시오 (data). 이 일을하는 동안 당신은 또한 차량 ID를 잘라내 수 있습니다

    import pandas as pd 
    
    # assuming CSV is named test.csv 
    f = open("test.csv", "r") 
    
    data = [] 
    for i, line in enumerate(f.readlines()): 
        splitted = line.split(",") 
        just_brand = [x.split("_")[0] for x in splitted] 
        data.append(just_brand) 
    
  2. 을 이제 우리는 파이썬 데이터 구조로 읽어 파일을 가지고, 우리는 파일 행을 재정렬 할 수 있도록 가장 많은 항목 필드가 맨 위에 있습니다. 누락 된 열을 추가 열보다 훨씬 잘 처리 할 수 ​​있으므로 Pandas에 좋습니다. 우리가 가장 많은 수의 열로 시작하면 더 짧은 연속 행이 정상적으로 처리됩니다. 여기에서

    df = pd.DataFrame(sorted(data, key=lambda row: len(row), reverse=True)) 
    
    df 
          0  1  2  3  4  5  6  7  8  9 
    0 10/14/2017 Region2 BMW BMW BMW TESLA TESLA TESLA TESLA TESLA 
    1 11/07/2017 Region2 TESLA BMW TESLA TESLA None None None None 
    2 11/02/2017 Region2 TESLA BMW TESLA TESLA None None None None 
    3 12/01/2017 Region1 BMW TESLA TESLA None None None None None 
    4 10/23/2017 Region1 BMW TESLA TESLA None None None None None 
    5 11/19/2017 Region2 BMW TESLA None None None None None None 
    
  3. , 그냥라는 조직과 형식의 물건을지고의 문제이다.

    df = (df.set_index([0,1]) 
         .stack() 
         .reset_index(level=1) 
         .rename(columns={1:"region",0:"make"}) 
         .reset_index(level=1, drop=True)) 
    
    df = (df.groupby([pd.to_datetime(df.index).month,"region","make"]) 
         .make.count() 
         .unstack() 
         .reset_index() 
         .rename(columns={0:"month"})) 
    df.columns.name = "" 
    
    df 
        region BMW TESLA month 
    0 Region1 1  2  10 
    1 Region2 3  5  10 
    2 Region2 3  7  11 
    3 Region1 1  2  12 
    
  4. (대체 덜 체조)

    # get TESLA, BMW counts for each row 
    cts = df.iloc[:,2:].apply(lambda x: x.value_counts(), axis=1) 
    # merge with date, region 
    df2 = pd.concat([df.iloc[:, :2], cts], axis=1) 
    # groupby and sum 
    (df2.groupby([pd.to_datetime(df[0]).dt.month,1]) 
        .sum() 
        .reset_index() 
        .rename(columns={0:"month",1:"region"})) 
    
  5. 아마도 관련
+0

"TESLA"와 "BMW"두 개의 int 열을 만들고 각 행에 각 행이 몇 번이나 저장된 경우 더 좋지 않겠습니까? 이렇게하면 훨씬 더 쉽게 처리 할 수 ​​있습니다. –

+0

Qusai Alothman, 귀하의 제안에 따라 솔루션을 추가했습니다. 감사! –

+0

@cataclysmic 당신을 환영합니다! –