解決済になっていますが、ベストアンサーとなっている回答が適当ではないので投稿します。
まず、辞書を用いて値を置換する際に、質問文では.replace()
メソッドを用いていますが、代わりに.map()
メソッドを用いると辞書のキーに存在せず置換されなかった値は自動的にNaN
に変換されます。
python
1In [11]: df["市区町村"].replace(dic)
2Out[11]:
30 100
41 90
52 池袋
63 50
74 45
85 80
9Name: 市区町村, dtype: object
10
11In [12]: df["市区町村"].map(dic)
12Out[12]:
130 100.0
141 90.0
152 NaN
163 50.0
174 45.0
185 80.0
19Name: 市区町村, dtype: float64
その結果、.replace()
メソッドを用いて得られたシリーズは整数型と文字列型が混在するobject
データ型になってしまっていますが、.map()
メソッドを用いて得られたシリーズはすべてが数値からなるfloat
データ型になっています(なお整数型になっていないのはint
データ型がNaN
を受け入れないためです)。
さらに、このとき.replace()
メソッドよりも.map()
メソッドのほうが高速に動作していることも注目に値します(この速度差はシリーズの行数が多いとさらに開きます)。
python
1In [13]: %timeit df["市区町村"].replace(dic)
2 ...: %timeit df["市区町村"].map(dic)
3694 µs ± 8.52 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
4475 µs ± 9.99 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
つづいて、値がNaN
となっているデータを特定の値で上書きする場合には、.fillna()
メソッドが利用できます。.map()
メソッドを用いたことがここで生きてきます。NaN
に変換したことで、わざわざ'池袋'
をキーにした辞書ライクなものを作成する必要がなくなり、シリーズの標準のメソッドを活用することができます。
シリーズの平均値で欠損値を穴埋めする場合は、Series.fillna(Series.mean))
のようにします。以下はこの動作の例です。
python
1In [14]: s = pd.Series([1, 2, None, 3, 4])
2
3In [15]: s.fillna(s.mean())
4Out[15]:
50 1.0
61 2.0
72 2.5
83 3.0
94 4.0
10dtype: float64
この動作を'都道府県'
列の値に基づいたグループごとに適用します。「シリーズを変更する動作を、グループごとに適用」は.groupby().transform()
を用います(.groupby().apply()
でも可能ですが適当ではありません)。
python
1In [16]: df['市区町村'].map(dic).groupby(df['都道府県']).transform(lambda s: s.fillna(s.mean()))
2Out[16]:
30 100.0
41 90.0
52 95.0
63 50.0
74 45.0
85 80.0
9Name: 市区町村, dtype: float64
このようにして得たシリーズをもとのdf
に再び割り当てることで、求めたい結果が得られます。
以下に今回の操作をまとめます。
python
1In [17]: pref = ["東京", "東京", "東京", "埼玉", "千葉", "神奈川"]
2 ...: value = ["渋谷", "新宿", "池袋", "大宮", "新浦安", "横浜"]
3 ...: df = pd.DataFrame({'都道府県':pref, '市区町村': value})
4 ...: dic = {"渋谷":100, "新宿":90, "大宮":50, "新浦安":45, "横浜":80}
5 ...:
6 ...: df
7Out[17]:
8 都道府県 市区町村
90 東京 渋谷
101 東京 新宿
112 東京 池袋
123 埼玉 大宮
134 千葉 新浦安
145 神奈川 横浜
15
16In [18]: df.assign(市区町村=df['市区町村'].map(dic).groupby(df['都道府県']).transform(lambda s: s.fillna(s.mean())))
17Out[18]:
18 都道府県 市区町村
190 東京 100.0
201 東京 90.0
212 東京 95.0
223 埼玉 50.0
234 千葉 45.0
245 神奈川 80.0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/02 04:29