DataFrameを縦方向に結合
日々のデータを一定期間ごとにcsvで取得し、結合する場合を想定しています。
csv
ファイルをDataFrame.read_csv
で取得し結合するときとかに使えると思います。
csv
ファイルをDataFrame.read_csv
で取得した結果がdf1、df2、df3を想定しています。
(df3はタイトル行に項目が増えている状態です)
import pandas as pd
df1 = pd.DataFrame([['2022/1/4', '500', '400', '40'],
['2022/1/5', '1000', '800', '80'],
['2022/1/6', '3000', '2400', '240']],
columns=['date', 'value', 'cost', 'tax'])
df1['date'] = pd.to_datetime(df1['date']).dt.date
df2 = pd.DataFrame([['2022/1/6', '3000', '2400', '240'],
['2022/1/7', '1000', '800', '80'],
['2022/1/8', '3000', '2400', '240'],
['2022/1/9', '1500', '1200', '120']],
columns=['date', 'value', 'cost', 'tax'])
df2['date'] = pd.to_datetime(df2['date']).dt.date
df3 = pd.DataFrame([['2022/1/9', '1500', '1200', '120', 'NaN'],
['2022/1/10', '500', '400', '40', '5'],
['2022/1/11', '1000', '800', '80', '10']],
columns=['date', 'value', 'cost', 'tax', 'tax2'])
df3['date'] = pd.to_datetime(df3['date']).dt.date
df1、df2、df3をconcat
で結合します。concat
だと、columnsが同じの場合はそのまま結合されます。
( ignore_index=True
を入れることでインデックスをつけなおします。 )
df = pd.concat([df1, df2, df3], ignore_index=True)
df
date | value | cost | tax | tax2 | |
---|---|---|---|---|---|
0 | 2022-01-04 | 500 | 400 | 40 | NaN |
1 | 2022-01-05 | 1000 | 800 | 80 | NaN |
2 | 2022-01-06 | 3000 | 2400 | 240 | NaN |
3 | 2022-01-06 | 3000 | 2400 | 240 | NaN |
4 | 2022-01-07 | 1000 | 800 | 80 | NaN |
5 | 2022-01-08 | 3000 | 2400 | 240 | NaN |
6 | 2022-01-09 | 1500 | 1200 | 120 | NaN |
7 | 2022-01-09 | 1500 | 1200 | 120 | NaN |
8 | 2022-01-10 | 500 | 400 | 40 | 5 |
9 | 2022-01-11 | 1000 | 800 | 80 | 10 |
append
でも同じことができます。複数を同時に結合する場合はcancat
のほうが良いかもしれませんが、for
文などを使って結合する場合はappend
が良いと思います。
( ignore_index=True
を入れることでインデックスをつけなおします。 )
df = pd.DataFrame()
for d in [df1, df2, df3]:
df = df.append(d, ignore_index=True)
df
date | value | cost | tax | tax2 | |
---|---|---|---|---|---|
0 | 2022-01-04 | 500 | 400 | 40 | NaN |
1 | 2022-01-05 | 1000 | 800 | 80 | NaN |
2 | 2022-01-06 | 3000 | 2400 | 240 | NaN |
3 | 2022-01-06 | 3000 | 2400 | 240 | NaN |
4 | 2022-01-07 | 1000 | 800 | 80 | NaN |
5 | 2022-01-08 | 3000 | 2400 | 240 | NaN |
6 | 2022-01-09 | 1500 | 1200 | 120 | NaN |
7 | 2022-01-09 | 1500 | 1200 | 120 | NaN |
8 | 2022-01-10 | 500 | 400 | 40 | 5 |
9 | 2022-01-11 | 1000 | 800 | 80 | 10 |
merge
でもkeyがわかっていれば使えますが、変わる場合は決めたエラーとなる場合があるので、注意が必要です。
df1、df2はcolumnsが一致しているが、df3は異なる。df3のcolumnsをkeyにすると'tax2'がdf1、df2に含まれていないため、エラーとなる。
mearge
の場合は外部結合how=outer
を設定する。重複行の削除も一度にできるメリットはあります。
key = list(df1.keys())
df = pd.DataFrame([], columns=key)
for d in [df1, df2, df3]:
df = df.merge(d, on=key, how='outer')
df
date | value | cost | tax | tax2 | |
---|---|---|---|---|---|
0 | 2022-01-04 | 500 | 400 | 40 | NaN |
1 | 2022-01-05 | 1000 | 800 | 80 | NaN |
2 | 2022-01-06 | 3000 | 2400 | 240 | NaN |
3 | 2022-01-07 | 1000 | 800 | 80 | NaN |
4 | 2022-01-08 | 3000 | 2400 | 240 | NaN |
5 | 2022-01-09 | 1500 | 1200 | 120 | NaN |
6 | 2022-01-10 | 500 | 400 | 40 | 5 |
7 | 2022-01-11 | 1000 | 800 | 80 | 10 |
concat
、append
で結合した場合は、drop_duplicates
で重複の削除ができる
df = pd.concat([df1, df2, df3], ignore_index=True)
df.drop_duplicates(subset='date', keep='last')
date | value | cost | tax | tax2 | |
---|---|---|---|---|---|
0 | 2022-01-04 | 500 | 400 | 40 | NaN |
1 | 2022-01-05 | 1000 | 800 | 80 | NaN |
3 | 2022-01-06 | 3000 | 2400 | 240 | NaN |
4 | 2022-01-07 | 1000 | 800 | 80 | NaN |
5 | 2022-01-08 | 3000 | 2400 | 240 | NaN |
7 | 2022-01-09 | 1500 | 1200 | 120 | NaN |
8 | 2022-01-10 | 500 | 400 | 40 | 5 |
9 | 2022-01-11 | 1000 | 800 | 80 | 10 |