1. ホーム
  2. python

[解決済み] pandas apply()から複数カラムを返す

2022-03-03 09:30:50

質問

pandasのDataFrameを持っています。 df_test . これは、バイト単位でサイズを表す列 'size' を含んでいます。 私は以下のコードを使ってKB、MB、GBを計算しました。

df_test = pd.DataFrame([
    {'dir': '/Users/uname1', 'size': 994933},
    {'dir': '/Users/uname2', 'size': 109338711},
])

df_test['size_kb'] = df_test['size'].astype(int).apply(lambda x: locale.format("%.1f", x / 1024.0, grouping=True) + ' KB')
df_test['size_mb'] = df_test['size'].astype(int).apply(lambda x: locale.format("%.1f", x / 1024.0 ** 2, grouping=True) + ' MB')
df_test['size_gb'] = df_test['size'].astype(int).apply(lambda x: locale.format("%.1f", x / 1024.0 ** 3, grouping=True) + ' GB')

df_test


             dir       size       size_kb   size_mb size_gb
0  /Users/uname1     994933      971.6 KB    0.9 MB  0.0 GB
1  /Users/uname2  109338711  106,776.1 KB  104.3 MB  0.1 GB

[2 rows x 5 columns]

120,000行で実行したところ、%timeitによると、1列あたり約2.97秒 * 3 = ~9秒かかることがわかりました。

もっと速くする方法はないでしょうか? 例えば、applyから一度に1列ずつ返して3回実行する代わりに、1回で3列全部を返して元のデータフレームに挿入することは可能でしょうか?

他の質問で見つけたのは、すべて次のようなものでした。 複数の値を取り、1つの値を返す . 私がしたいのは 一つの値を取り、複数の列を返す .

どのように解決するのですか?

適用した関数から新しいデータを含むSeriesを返すことで、3回反復する必要がなくなります。 渡し方 axis=1 を適用関数に渡すと、その関数 sizes をデータフレームの各行に適用し、新しいデータフレームに追加するための系列を返します。 この系列 s には、元のデータだけでなく、新しい値も含まれます。

def sizes(s):
    s['size_kb'] = locale.format("%.1f", s['size'] / 1024.0, grouping=True) + ' KB'
    s['size_mb'] = locale.format("%.1f", s['size'] / 1024.0 ** 2, grouping=True) + ' MB'
    s['size_gb'] = locale.format("%.1f", s['size'] / 1024.0 ** 3, grouping=True) + ' GB'
    return s

df_test = df_test.append(rows_list)
df_test = df_test.apply(sizes, axis=1)