パンダ:長い形式のデータフレームに値がないにもかかわらず、すべての行にすべての列を含めるにはどうすればよいですか?

Aug 23 2020

これは最初は奇妙な質問のように聞こえるかもしれませんが、のデータの要素について話すときに「標準的な」用語を見つけるのは難しいと思いましたlong format。だから私は、ハドリー・ウィッカムがTidyDataに関する彼の記事の最初の例の1つで使用しているのと同じ用語を使用したいと思いました。

私の実際のデータのサンプルでは、行には日付が含まれ列にはカテゴリが含まれ値には次のような価格が含まれています

入力

    row         column  value
0   21.08.2020  A       43
1   21.08.2020  A       36
2   21.08.2020  B       36
3   21.08.2020  C       28
4   22.08.2020  A       16
5   22.08.2020  B       40
6   22.08.2020  B       34

ここでは、column値は上の画像ほど規則的ではありません。一部の行値で一部の列値が欠落しています。値をに設定して同じデータセットにこれらの列名を含めるにはどうすればよい0ですか?上記のサンプルデータフレームでは、次の場合にcolumn Cのみ発生しrow = 21.08.2020ます。

これを考慮して含めることができるパンダ関数はあります22.08.2020 C 0か?

必要な出力

    row         column  value
0   21.08.2020  A       43
1   21.08.2020  A       36
2   21.08.2020  B       36
3   21.08.2020  C       28
4   22.08.2020  A       16
5   22.08.2020  B       40
6   22.08.2020  B       34
7   22.08.2020  C       0

すべてを取得しunique column values = ['A', 'B', 'C']、すべての行の値をループしてvalue = 0、欠落している列を挿入するアプローチを試しましたが、それは非常に高速になりました。だから他の提案は素晴らしいでしょう!

編集:pd.pivotを使用して長いものから広いものへ

を使用pd.pivot_table(df1,index='row',columns='column',values='value')すると、上記の入力データフレームが次のようになります。

column      A       B       C
row         
21.08.2020  39.5    36.0    28.0
22.08.2020  16.0    37.0    NaN

ここでは、NaNデフォルトで含まれているcolumn=Crow=22.08.2020。したがって、このデータフレームを削除せずに目的の出力にメルトまたはピボットする場合が残りNaNます。

編集2:サンプルデータフレーム

import pandas as pd
df=pd.DataFrame({'row': {0: '21.08.2020',
  1: '21.08.2020',
  2: '21.08.2020',
  3: '21.08.2020',
  4: '22.08.2020',
  5: '22.08.2020',
  6: '22.08.2020'},
 'column': {0: 'A', 1: 'A', 2: 'B', 3: 'C', 4: 'A', 5: 'B', 6: 'B'},
 'value': {0: 43, 1: 36, 2: 36, 3: 28, 4: 16, 5: 40, 6: 34}})

回答

2 BENY Aug 23 2020 at 06:32

同じ行に複数の値があるため、これは前のものとは異なります

df['key']=df.groupby(['row','column']).cumcount()

df1 = pd.pivot_table(df,index='row',columns=['key','column'],values='value')

df1 = df1.stack(level=[0,1],dropna=False).to_frame('value').reset_index()

df1 = df1[df1.key.eq(0) | df1['value'].notna()]
df1
Out[97]: 
           row  key column  value
0   21.08.2020    0      A   43.0
1   21.08.2020    0      B   36.0
2   21.08.2020    0      C   28.0
3   21.08.2020    1      A   36.0
6   22.08.2020    0      A   16.0
7   22.08.2020    0      B   40.0
8   22.08.2020    0      C    NaN
10  22.08.2020    1      B   34.0
1 vestland Aug 23 2020 at 06:09

pd.pivot()はと組み合わせてアプローチを見つけましたunstack()

import pandas as pd
df=pd.DataFrame({'row': {0: '21.08.2020',
  1: '21.08.2020',
  2: '21.08.2020',
  3: '21.08.2020',
  4: '22.08.2020',
  5: '22.08.2020',
  6: '22.08.2020'},
 'column': {0: 'A', 1: 'A', 2: 'B', 3: 'C', 4: 'A', 5: 'B', 6: 'B'},
 'value': {0: 43, 1: 36, 2: 36, 3: 28, 4: 16, 5: 40, 6: 34}})

df1 = pd.pivot_table(df,index='row',columns='column',values='value').unstack().reset_index() 
print(df1)

出力

    column  row         0
0   A       21.08.2020  39.5
1   A       22.08.2020  16.0
2   B       21.08.2020  36.0
3   B       22.08.2020  37.0
4   C       21.08.2020  28.0
5   C       22.08.2020  NaN

ただし、データフレーム列の順序は間違いなく混乱しています...

1 wwii Aug 23 2020 at 06:40

これは単純なアプローチです-forループを使用します。

data = {'row': {0: '21.08.2020', 1: '21.08.2020', 2: '21.08.2020',
                3: '21.08.2020', 4: '22.08.2020', 5: '22.08.2020',
                6: '22.08.2020'},
        'column': {0: 'A', 1: 'A', 2: 'B', 3: 'C', 4: 'A', 5: 'B', 6: 'B'},
        'value': {0: 43, 1: 36, 2: 36, 3: 28, 4: 16, 5: 40, 6: 34}}

df = pd.DataFrame(data)

categories = set(df.column.unique())
tbl = pd.pivot_table(df[['row','column']],values='column',index='row',aggfunc=set)

missing = tbl.column.apply(categories.difference)
missing = filter(lambda x:x[1],missing.items())

d = collections.defaultdict(list)
#d = {'row':[],'column':[],'value':[]}
for row,col in missing:
    for cat in col:
        d['row'].append(row)
        d['column'].append(cat)
        d['value'].append(0)

df2 = df.append(pd.DataFrame(d))。reset_index()

df2 = df.append(pd.DataFrame(d)).reset_index()

もちろん、すべての新しい値は最後になり、それが問題になる場合は並べ替える必要があります。


中間オブジェクト:

>>> tbl
               column
row                  
21.08.2020  {A, B, C}
22.08.2020     {A, B}
>>> missing
row
21.08.2020     {}
22.08.2020    {C}
Name: column, dtype: object
>>>
1 sammywemmy Aug 23 2020 at 10:44

ここでalternative.itが設定されrow且つcolumn、新たなインデックスとして列をの値のすべての可能な組み合わせを取得rowし、column列、及びジョイン(方法=「外側」)を持つ空のデータフレームrowcolumn新しい指標としての組合せ:

 From itertools import product
new_index = product(set(df.row.array), set(df.column.array))
df = df.set_index(["row", "column"])
new_index = pd.DataFrame([], index=pd.Index(new_index, names=["row", "column"]))
df.join(new_index, how="outer").reset_index().astype({"value": "Int8"}) # if you are keen on nullable integers

    row      column value
0   21.08.2020  A   43
1   21.08.2020  A   36
2   21.08.2020  B   36
3   21.08.2020  C   28
4   22.08.2020  A   16
5   22.08.2020  B   40
6   22.08.2020  B   34
7   22.08.2020  C   <NA>