programing

번식 가능한 좋은 판다를 만드는 방법

procenter 2022. 9. 24. 22:17
반응형

번식 가능한 좋은 판다를 만드는 방법

과 panda가 SO를 붙이는 것을 보면서 느낀 인상은pandas질문은 재현 가능한 데이터를 포함할 가능성이 낮습니다.이것은 R커뮤니티에서 꽤 좋은 평가를 받고 있는 것으로, 이러한 가이드 덕분에, 신참자들은 이러한 사례들을 정리하는 데 도움을 받을 수 있습니다.이러한 가이드를 읽고 재현 가능한 데이터를 가지고 돌아올 수 있는 사람들은 종종 그들의 질문에 대한 답을 얻는 것이 훨씬 더 행운일 것이다.

하면 수 요?pandas★★★★★★★★★★★★★★★★★?심플한 데이터 프레임을 정리할 수 있습니다.

import pandas as pd
df = pd.DataFrame({'user': ['Bob', 'Jane', 'Alice'], 
                   'income': [40000, 50000, 42000]})

그러나 많은 예제 데이터 세트에는 다음과 같은 보다 복잡한 구조가 필요합니다.

  • datetime 또는
  • 변수하는 R이 ?)expand.grid()특정 변수의 가능한 모든 조합을 생성하는 함수)
  • 멀티인덱스 또는 패널 데이터

하는 것이 ?dput()데이터 구조를 재생성하기 위한 복사 가능한 코드를 생성할 수 있습니다.

주의: 여기에서는 Stack Overflow에 대한 일반적인 의견을 제시합니다.

면책사항:좋은 질문을 쓰는 것은 어렵다.

장점:

  • 실행 가능한 코드 중 하나로 작은* 예제 DataFrame을 포함합니다.

    In [1]: df = pd.DataFrame([[1, 2], [1, 3], [4, 6]], columns=['A', 'B'])
    

    해서 붙여넣기'를 해서 '해서 붙여넣기를 할 요.pd.read_clipboard(sep='\s\s+')Stack Overflow 하이라이트의 텍스트 형식을 지정하여 +(K또는 각 행에 4칸씩 추가)를 사용하거나 코드 위아래에 3개의 백틱(')을 삽입할 수 있습니다.

    In [2]: df
    Out[2]:
       A  B
    0  1  2
    1  1  3
    2  4  6
    

    pd.read_clipboard(sep='\s\s+')네 자신.

    * 말은 정말 작다는 거야. 데이터 프레임의 대부분은 6행 미만일 수 있으며, 5행으로 할 수 있습니다. 로 에러를 재현할 수 있습니까?그렇지 않은 경우는, 작은 데이터 프레임으로 문제를 해결할 수 있는지 확인해 주세요.

    * 모든 규칙에는 예외가 있습니다.명백한 예외는 퍼포먼스 문제(이 경우 %timeit을 사용하고 %prun을 사용할 수 있음)에 대한 것입니다.여기서 :을 생성할 필요가 있습니다. 같은 프레임이 되도록 사용하는 것을 검토해 주십시오. 「이 코드를 빨리 해 주세요」라고 하는 것은, 사이트의 토픽에 한정되어 있지 않습니다.

  • 원하는 결과를 기입한다(위 참조).

    In [3]: iwantthis
    Out[3]:
       A  B
    0  1  5
    1  4  6
    

    숫자의 출처를 설명합니다.A가 1인 행에 대한 B 열의 합계가 5입니다.

  • 시도한 코드를 표시합니다.

    In [4]: df.groupby('A').sum()
    Out[4]:
       B
    A
    1  5
    4  6
    

    그러나 무엇이 틀렸는지 말해보세요: A 열은 열이 아니라 인덱스에 있습니다.

  • 조사(문서 검색, 스택 오버플로 검색)를 하고 요약을 제공합니다.

    sum에 대한 docstring은 단순히 "그룹 값의 합계 계산"을 나타냅니다.

    그룹별 문서에는 이에 대한 예가 나와 있지 않습니다.

    외:에서는, 「 」를 합니다.「 」df.groupby('A', as_index=False).sum().

  • 경우 등하십시오.pd.to_datetime** 입니다.

    df['date'] = pd.to_datetime(df['date']) # this column ought to be date..
    

    ** 때때로 이것은 문제 그 자체입니다: 그것들은 끈이었습니다.

나쁜 점:

  • 복사하여 붙여넣을 수 없는 MultiIndex는 포함하지 않습니다(위 참조).이것은 판다의 디폴트 디스플레이에 대한 일종의 불만이지만, 그럼에도 불구하고 성가시다.

    In [11]: df
    Out[11]:
         C
    A B
    1 2  3
      2  6
    

    올바른 방법은 일반 Data Frame을 호출에 포함시키는 것입니다.

    In [12]: df = pd.DataFrame([[1, 2, 3], [1, 2, 6]], columns=['A', 'B', 'C']).set_index(['A', 'B'])
    
    In [13]: df
    Out[13]:
         C
    A B
    1 2  3
      2  6
    
  • 원하는 결과를 제공할 때 어떤 의미인지 파악할 수 있습니다.

       B
    A
    1  1
    5  0
    

    번호를 어떻게 취득했는지 구체적으로 알려주세요(정확히 말해 주세요.다시 한 번 확인해 봐

  • 코드가 에러를 발생시키는 경우는, 스택 트레이스 전체를 포함합니다(이것은 나중에 노이즈가 심한 경우는 편집할 수 있습니다).회선 번호(및 그 번호가 나타내는 코드의 대응하는 회선)를 표시합니다.

미운 점:

  • 액세스 할 수 없는 CSV 파일에 링크하지 않는다(이상적으로는 외부 소스에 전혀 링크하지 않는다).

    df = pd.read_csv('my_secret_file.csv')  # ideally with lots of parsing options
    

    대부분의 데이터는 소유권입니다.유사한 데이터를 작성하여 문제를 재현할 수 있는지 확인합니다(작은 것).

  • "대형"인 데이터 프레임이 있는 것처럼 상황을 애매하게 설명하지 말고 일부 열 이름을 지나가면서 언급하십시오(dtype은 언급하지 마십시오).실제 맥락을 보지 않고는 전혀 의미가 없는 것에 대해 많은 세부사항을 설명하려고 노력하세요.아마도 아무도 이 단락을 끝까지 읽지 않을 것이다.

    에세이는 나쁘고, 작은 예시가 더 쉽다.

  • 10+(100+)는 포함하지 않는다.실제 질문에 도달하기 전에 몇 줄의 데이터가 지워집니다.

    제발, 우리 일상 업무에서는 이런 걸 충분히 볼 수 있어요돕고 싶지만 이런 식으로는... 도입 부분을 잘라내고 문제가 발생하고 있는 관련 데이터 프레임(또는 데이터 프레임의 작은 버전)을 보여 줍니다.

아무튼 파이썬, NumPy, Panda를 재미있게 배워보세요!

샘플 데이터셋 작성 방법

이는 주로 샘플 데이터 프레임을 작성하는 방법의 예를 제공함으로써 AndyHayden의 답변을 확대하기 위한 것입니다.Panda와 (특히) NumPy는 이를 위한 다양한 툴을 제공하여 일반적으로 코드 몇 줄만으로 실제 데이터셋의 합리적인 팩시밀리를 만들 수 있습니다.

NumPy와 Panda를 Import한 후 데이터와 결과를 정확하게 재현할 수 있도록 하려면 랜덤 시드를 제공해야 합니다.

import numpy as np
import pandas as pd

np.random.seed(123)

부엌 싱크대 예시

여기 여러분이 할 수 있는 다양한 것들을 보여주는 예가 있습니다.다음의 서브셋으로부터, 모든 종류의 유용한 샘플 데이터 프레임을 작성할 수 있습니다.

df = pd.DataFrame({

    # some ways to create random data
    'a':np.random.randn(6),
    'b':np.random.choice( [5,7,np.nan], 6),
    'c':np.random.choice( ['panda','python','shark'], 6),

    # some ways to create systematic groups for indexing or groupby
    # this is similar to R's expand.grid(), see note 2 below
    'd':np.repeat( range(3), 2 ),
    'e':np.tile(   range(2), 3 ),

    # a date range and set of random dates
    'f':pd.date_range('1/1/2011', periods=6, freq='D'),
    'g':np.random.choice( pd.date_range('1/1/2011', periods=365,
                          freq='D'), 6, replace=False)
    })

그 결과, 다음과 같이 됩니다.

          a   b       c  d  e          f          g
0 -1.085631 NaN   panda  0  0 2011-01-01 2011-08-12
1  0.997345   7   shark  0  1 2011-01-02 2011-11-10
2  0.282978   5   panda  1  0 2011-01-03 2011-10-30
3 -1.506295   7  python  1  1 2011-01-04 2011-09-07
4 -0.578600 NaN   shark  2  0 2011-01-05 2011-02-27
5  1.651437   7  python  2  1 2011-01-06 2011-02-03

주의사항:

  1. np.repeat ★★★★★★★★★★★★★★★★★」np.tile (비밀(이행)d ★★★★★★★★★★★★★★★★★」e및할 때 는 그룹 및 인덱스를 매우 정기적으로 작성할 때 매우 유용합니다.r의 을 쉽게 할 수 .expand.grid()또한 모든 순열의 부분 집합을 제공하는 능력이 더 유연합니다.그러나 열이 3개 이상일 경우 구문은 빠르게 다루기 어려워집니다.
  2. 의 R을 expand.grid()itertools팬더 요리책 또는 그 안에 있는 해결책np.meshgrid를 참조해 주세요.그것들은 임의의 수의 차원을 허용한다.
  3. 하면 할 수요.np.random.choice를 들어,에는 . 를, 、 . . 。g 6월 6일부터 할 수 있습니다. 「」를 설정해 .replace=False이러한 날짜는 고유하며 고유한 값을 가진 인덱스로 사용할 경우 매우 편리합니다.

가짜 주식 시장 데이터

상기 코드의 서브셋을 취득하는 것 외에, 그 기술을 조합해 거의 모든 것을 실행할 수 있습니다.예를 들어, 여기 다음과 같은 간단한 예가 있습니다.np.tile ★★★★★★★★★★★★★★★★★」date_range동일한 날짜를 포함하는 4개 재고의 표본 티커 데이터를 생성하는 방법:

stocks = pd.DataFrame({
    'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
    'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
    'price':(np.random.randn(100).cumsum() + 10) })

이제 100줄(티커당 25일)의 샘플 데이터셋이 있지만 4줄만 사용하여 코드를 복사하고 붙여넣지 않고도 쉽게 복제할 수 있습니다.그런 다음 질문을 설명하는 데 도움이 될 경우 데이터의 하위 집합을 표시할 수 있습니다.

>>> stocks.head(5)

        date      price ticker
0 2011-01-01   9.497412   aapl
1 2011-01-02  10.261908   aapl
2 2011-01-03   9.438538   aapl
3 2011-01-04   9.515958   aapl
4 2011-01-05   7.554070   aapl

>>> stocks.groupby('ticker').head(2)

         date      price ticker
0  2011-01-01   9.497412   aapl
1  2011-01-02  10.261908   aapl
25 2011-01-01   8.277772   goog
26 2011-01-02   7.714916   goog
50 2011-01-01   5.613023   yhoo
51 2011-01-02   6.397686   yhoo
75 2011-01-01  11.736584   msft
76 2011-01-02  11.944519   msft

해답가의 일기

질문을 할 때 가장 좋은 조언은 질문에 대답하는 사람들의 심리를 이용하는 것입니다.그런 사람들 중 한 명으로서, 나는 왜 내가 특정한 질문에 대답하는지 그리고 왜 다른 사람들에게 대답하지 않는지에 대한 통찰력을 줄 수 있다.

동기

나는 몇 가지 이유로 질문에 대답할 의욕이 있다.

  1. Stackoverflow.com은 저에게 매우 귀중한 자료였습니다.돌려주고 싶었어
  2. 이 사이트가 예전보다 더 강력한 자원이라는 것을 알게 되었습니다.질문에 대답하는 것은 저에게 학습 경험이고 저는 배우는 것을 좋아합니다.이 답을 읽고 다른 수의사의 코멘트를 받아보세요.이런 상호작용은 나를 행복하게 해.
  3. 나 점수 좋아해!
  4. 3번 참조.
  5. 나는 재미있는 문제를 좋아한다.

저의 순수한 의도는 모두 훌륭하지만, 한 가지 질문이나 30가지 답변을 하면 만족감을 얻을 수 있습니다.어떤 질문에 대답해야 할지 선택하는 원동력은 포인트 최대화라는 큰 요소입니다.

나는 또한 흥미로운 문제에 시간을 할애할 것이다. 그러나 그것은 매우 드물고 흥미롭지 않은 질문에 대한 해답을 필요로 하는 질문자에게 도움이 되지 않는다.내가 질문에 대답하게 하는 최선의 방법은 그 질문을 접시에 담아 가능한 한 쉽게 대답할 수 있도록 하는 것이다.두 개의 질문을 보고 있고 한 개의 질문이 코드를 가지고 있는 경우 복사 붙여넣기를 통해 필요한 변수를 모두 생성할 수 있습니다.저걸로 할게요!시간이 나면 다른 곳으로 다시 올지도 몰라요.

주요 조언

사람들이 질문에 쉽게 대답할 수 있도록 하세요.

  • 필요한 변수를 생성하는 코드를 제공합니다.
  • 코드를 최소화하세요.게시물을 볼 때 눈이 흐려지면 다음 질문으로 넘어가거나 제가 하고 있는 다른 일로 돌아갑니다.
  • 무엇을 묻고 싶은지 생각하고 구체적으로 말해라.자연어(영어)는 정확하지 않고 혼란스럽기 때문에 우리는 당신이 무엇을 했는지 보고 싶습니다.시도한 코드 샘플은 자연 언어 설명의 불일치를 해결하는 데 도움이 됩니다.
  • 기대해주세요!!!난 앉아서 뭔가를 시도해야 해.나는 어떤 것을 시도하지 않고는 질문에 대한 답을 거의 알지 못한다.당신이 찾고 있는 것의 예를 볼 수 없다면, 저는 추측하고 싶지 않기 때문에 질문을 던질지도 모릅니다.

당신의 평판은 단순한 평판 그 이상입니다.

저는 포인트를 좋아합니다(위에서 말씀드렸습니다).하지만 그 점들은 사실 제 평판이 아닙니다.내 진짜 평판은 사이트에 있는 다른 사람들이 나에 대해 어떻게 생각하는지 섞은 것이다.나는 공정하고 정직하기 위해 노력하고 있고 다른 사람들이 그것을 볼 수 있기를 바란다.그것은 질문자에게 있어서 우리는 질문자의 행동을 기억한다는 것을 의미합니다.만약 당신이 답을 선택하지 않고 좋은 답을 상향 투표하지 않는다면, 나는 기억합니다.당신이 내가 싫어하는 방식이나 내가 좋아하는 방식으로 행동한다면, 나는 기억합니다.이것도 제가 대답할 질문의 대상입니다.


어쨌든, 계속 할 수는 있겠지만, 실제로 이 글을 읽는 여러분 모두를 용서하겠습니다.

과제 SO 질문에 대한 대응에서 가장 어려운 측면 중 하나는 문제(데이터 포함)를 재현하는 데 걸리는 시간입니다.데이터를 재현할 수 있는 명확한 방법이 없는 질문은 답변할 가능성이 낮아집니다.질문 작성에 시간을 할애하고 있고, 도움이 필요한 문제가 있는 경우, 다른 사람이 문제를 해결하는 데 사용할 수 있는 데이터를 제공함으로써 쉽게 문제를 해결할 수 있습니다.

@Andy가 제공하는 좋은 판다 질문 작성에 대한 설명은 시작하기에 아주 좋은 장소입니다.자세한 내용은 최소, 완료 검증 가능한 예제의 작성 방법과 작성 방법참조하십시오.

질문 내용을 명확하게 말씀해 주세요.시간을 들여 질문과 샘플 코드를 작성한 후 문제를 요약하고 질문을 명확하게 설명하는 '이그제큐티브 요약'을 독자에게 제공합니다.

번째 질문:

이 데이터가 있는데...

나 이거 하고 싶어...

결과가 이렇게 나왔으면 좋겠는데...

그러나 [이것]을 하려고 하면 다음과 같은 문제가 발생합니다.

나는 이것저것 하면서 해결책을 찾으려고 노력했다.

어떻게 고치죠?

제공된 데이터 양, 샘플 코드 및 오류 스택에 따라 문제가 무엇인지 이해하기까지는 상당한 시간이 필요합니다.질문 자체가 맨 위에 오도록 질문을 다시 한 번 한 후 필요한 세부 정보를 제공하세요.

수정된 질문:

질문:어떻게 하면 좋을까요?

나는 이것저것 하면서 해결책을 찾으려고 노력했다.

이것을 하려고 하면, 다음과 같은 문제가 발생합니다.

제 최종 결과는 이렇게 나왔으면 좋겠는데...

여기 내 문제를 재현할 수 있는 최소한의 코드가 있습니다.

다시 은 다음과 .df = pd.DataFrame({'A': [...], 'B': [...], ...})

필요한 경우 샘플 데이터 제공!!!

Data Frame의 머리나 꼬리만 있으면 되는 경우도 있습니다.또한 @JohnE에서 제안한 방법을 사용하여 다른 사용자가 복제할 수 있는 더 큰 데이터 세트를 만들 수도 있습니다.예를 들어 100행의 Data Frame 주가를 생성하는 방법:

stocks = pd.DataFrame({ 
    'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
    'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
    'price':(np.random.randn(100).cumsum() + 10) })

실제 데이터인 경우 다음과 같이 데이터 프레임의 머리 및/또는 꼬리를 포함할 수 있습니다(중요한 데이터는 익명화하십시오).

>>> stocks.head(5).to_dict()
{'date': {0: Timestamp('2011-01-01 00:00:00'),
  1: Timestamp('2011-01-01 00:00:00'),
  2: Timestamp('2011-01-01 00:00:00'),
  3: Timestamp('2011-01-01 00:00:00'),
  4: Timestamp('2011-01-02 00:00:00')},
 'price': {0: 10.284260107718254,
  1: 11.930300761831457,
  2: 10.93741046217319,
  3: 10.884574289565609,
  4: 11.78005850418319},
 'ticker': {0: 'aapl', 1: 'aapl', 2: 'aapl', 3: 'aapl', 4: 'aapl'}}

>>> pd.concat([stocks.head(), stocks.tail()], ignore_index=True).to_dict()
{'date': {0: Timestamp('2011-01-01 00:00:00'),
  1: Timestamp('2011-01-01 00:00:00'),
  2: Timestamp('2011-01-01 00:00:00'),
  3: Timestamp('2011-01-01 00:00:00'),
  4: Timestamp('2011-01-02 00:00:00'),
  5: Timestamp('2011-01-24 00:00:00'),
  6: Timestamp('2011-01-25 00:00:00'),
  7: Timestamp('2011-01-25 00:00:00'),
  8: Timestamp('2011-01-25 00:00:00'),
  9: Timestamp('2011-01-25 00:00:00')},
 'price': {0: 10.284260107718254,
  1: 11.930300761831457,
  2: 10.93741046217319,
  3: 10.884574289565609,
  4: 11.78005850418319,
  5: 10.017209045035006,
  6: 10.57090128181566,
  7: 11.442792747870204,
  8: 11.592953372130493,
  9: 12.864146419530938},
 'ticker': {0: 'aapl',
  1: 'aapl',
  2: 'aapl',
  3: 'aapl',
  4: 'aapl',
  5: 'msft',
  6: 'msft',
  7: 'msft',
  8: 'msft',
  9: 'msft'}}

데이터 프레임에 대한 설명을 제공할 수도 있습니다(관련 열만 사용).이를 통해 다른 사용자가 각 열의 데이터 유형을 확인하고 다른 일반적인 오류(예: 날짜 vs. datetime64 vs. object)를 쉽게 식별할 수 있습니다.

stocks.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100 entries, 0 to 99
Data columns (total 3 columns):
date      100 non-null datetime64[ns]
price     100 non-null float64
ticker    100 non-null object
dtypes: datetime64[ns](1), float64(1), object(1)

메모: 데이터 프레임에 MultiIndex가 있는 경우:

멀티인덱스가 후 ""를해야 합니다.to_dict를 다시 set_index:

# MultiIndex example.  First create a MultiIndex DataFrame.
df = stocks.set_index(['date', 'ticker'])
>>> df
                       price
date       ticker           
2011-01-01 aapl    10.284260
           aapl    11.930301
           aapl    10.937410
           aapl    10.884574
2011-01-02 aapl    11.780059
...

# After resetting the index and passing the DataFrame to `to_dict`, make sure to use 
# `set_index` to restore the original MultiIndex.  This DataFrame can then be restored.

d = df.reset_index().to_dict()
df_new = pd.DataFrame(d).set_index(['date', 'ticker'])
>>> df_new.head()
                       price
date       ticker           
2011-01-01 aapl    10.284260
           aapl    11.930301
           aapl    10.937410
           aapl    10.884574
2011-01-02 aapl    11.780059

여기 판다를 위한 내 버전 - 재현 가능한 보고서 작성을 위한 표준 R 도구 -DataFrame 더 이 높지만 에서는 효과가 것 . 더 복잡한 프레임에서는 실패할 가능성이 높지만, 다음과 같은 간단한 경우에서 작업이 수행될 수 있습니다.

import pandas as pd
def dput(x):
    if isinstance(x,pd.Series):
        return "pd.Series(%s,dtype='%s',index=pd.%s)" % (list(x),x.dtype,x.index)
    if isinstance(x,pd.DataFrame):
        return "pd.DataFrame({" + ", ".join([
            "'%s': %s" % (c,dput(x[c])) for c in x.columns]) + (
                "}, index=pd.%s)" % (x.index))
    raise NotImplementedError("dput",type(x),x)

지금이다,

df = pd.DataFrame({'a':[1,2,3,4,2,1,3,1]})
assert df.equals(eval(dput(df)))
du = pd.get_dummies(df.a,"foo")
assert du.equals(eval(dput(du)))
di = df
di.index = list('abcdefgh')
assert di.equals(eval(dput(di)))

이것에 의해, 다음과 같은 보다 상세한 출력이 생성되는 것에 주의해 주세요.

pd.DataFrame({
  'foo_1':pd.Series([1, 0, 0, 0, 0, 1, 0, 1],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_2':pd.Series([0, 1, 0, 0, 1, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_3':pd.Series([0, 0, 1, 0, 0, 0, 1, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_4':pd.Series([0, 0, 0, 1, 0, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1))},
  index=pd.RangeIndex(start=0, stop=8, step=1))

{'foo_1': {0: 1, 1: 0, 2: 0, 3: 0, 4: 0, 5: 1, 6: 0, 7: 1}, 
 'foo_2': {0: 0, 1: 1, 2: 0, 3: 0, 4: 1, 5: 0, 6: 0, 7: 0}, 
 'foo_3': {0: 0, 1: 0, 2: 1, 3: 0, 4: 0, 5: 0, 6: 1, 7: 0}, 
 'foo_4': {0: 0, 1: 0, 2: 0, 3: 1, 4: 0, 5: 0, 6: 0, 7: 0}}

★★★★★★에du열 유형을 보존합니다.예: 위의 테스트 케이스에서

du.equals(pd.DataFrame(du.to_dict()))
==> False

du.dtypesuint8 ★★★★★★★★★★★★★★★★★」pd.DataFrame(du.to_dict()).dtypesint64.

언급URL : https://stackoverflow.com/questions/20109391/how-to-make-good-reproducible-pandas-examples

반응형