編集:私は自分の問題を単純化しすぎていることに気づきました。これはおそらく、提案されたソリューションが元のブルートフォースソリューションと同じように機能すると想定したためです。問題をわかりやすくするために、多重指数を変更しました。すでに努力してくださった方々、お詫び申し上げます。ありがとうございました!
マルチインデックスのパンダデータフレームがあります。インデックスに3つのレベルがあり、2番目のレベルに色の名前が含まれているとします。各行blue
で、インデックスの色を持つすべての列にNaN
1つを除いて含まれていることを知っているので、次のようになります。
import pandas as pd
import numpy as np
iterables = [['bar', 'baz', 'foo', 'qux'], ["red", "blue", "green"], ['one', 'two']]
mi = pd.MultiIndex.from_product(iterables)
df = pd.DataFrame(np.random.randn(5, 24), columns=mi)
df[("bar", "blue","one")] = [2 , np.nan, np.nan, 3 , np.nan]
df[("baz", "blue","two")] = [np.nan, 4.4 , np.nan, np.nan, 5 ]
df[("qux", "blue","one")] = [np.nan, np.nan, 1 , np.nan, np.nan]
出力:
bar ... qux
red blue green ... red blue green
one two one two one two ... one two one two one two
0 0.046326 -0.999092 2.0 0.073113 0.958438 0.276653 ... -0.258202 -0.772636 NaN -0.639735 1.438262 -0.033578
1 0.257776 -2.499286 NaN 0.854263 -0.037380 -0.571258 ... 1.656198 -1.110911 NaN 0.757692 0.498118 1.070371
2 -0.314146 0.941367 NaN 0.265850 -0.153231 -1.092106 ... -0.208089 -0.363624 1.0 0.046457 -2.158373 0.572496
3 -1.198977 0.605490 3.0 -0.790985 0.000563 -0.958261 ... 1.339086 -1.057270 NaN -0.355639 1.050980 -1.727684
4 -0.562230 -1.721894 NaN 0.856543 -1.137364 1.185481 ... 0.986215 1.028128 NaN -0.264889 0.571484 -0.505340
ここで、行がそれぞれの列に持つ非nan値を含み、その多重指数の他の指数にも名前を付ける新しいデータフレームを作成したいと思います。
word number blue
0 bar one 2.0
1 baz two 4.4
2 qux one 1.0
3 bar one 3.0
4 baz two 5.0
つまり、新しいデータフレームのword
andnumber
エントリは、元のデータフレームが非nan値を持っていたインデックスであり、新しいblue
列には値が含まれている必要があります。
基本的にすべてのエントリを反復処理するブルートフォースソリューションがありますが、最終的なデータフレームには約2000列が含まれ、実行に非常に時間がかかります。
で選択した場合DataFrame.xs
のみによって再構築DataFrame.stack
、することにより、第1マルチインデックスレベルを削除reset_index
してdrop=True
、最後の変換Series
に2
列DataFrame
によるSeries.rename_axis
とSeries.reset_index
:
df = (df.xs('blue', axis=1, level=1)
.stack()
.reset_index(level=0, drop=True)
.rename_axis('number')
.reset_index(name='blue'))
print (df)
number blue
0 1 2.0
1 2 4.4
2 3 1.0
3 1 3.0
4 2 5.0
編集:解決策は似ていますが、少なくとも1つNaN
の列をDataFrame.isna
とDataFrame.any
でフィルタリングするだけで、両方のレベルでDataFrame.loc
使用さDataFrame.stack
れMultiIndex
ます。
df1 = (df.loc[:, df.isna().any()]
.xs('blue', axis=1, level=1)
.stack([0,1])
.reset_index(level=0, drop=True)
.rename_axis(('word','number'))
.reset_index(name='blue'))
print (df1)
word number blue
0 bar one 2.0
1 baz two 4.4
2 qux one 1.0
3 bar one 3.0
4 baz two 5.0
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加