[英]Merge multiple time columns into a single column using wide_to_long
我有一個 dataframe,它有多個時間列和一個賦值。
import pandas as pd
df = pd.DataFrame({'time': {0: 0.2, 1: 0.3, 2: 0.4, 3: nan}, 'val1': {0: 1.0, 1: 3.0, 2: 1.0, 3: nan}, 'time2': {0: 0.1, 1: 0.4, 2: 0.8, 3: 1.0}, 'val2': {0: 2, 1: 2, 2: 9, 3: 2}})
看起來像這樣:
time val1 time2 val2
0 0.2 1.0 0.1 2
1 0.3 3.0 0.4 2
2 0.4 1.0 0.8 9
3 NaN NaN 1.0 2
可以有更多的時間和值列(但它們總是成對出現)。 我想將所有時間列合並到一個列中,同時將val
保留並填充到它們相應的時間。
示例 output:
time val1 val2
0 0.1 1.0 2.0
1 0.2 1.0 2.0
2 0.3 3.0 2.0
3 0.4 1.0 2.0
4 0.8 1.0 9.0
5 1.0 1.0 2.0
我以前問過這個問題,一個答案非常接近:答案和下面的 output:
df1 = (pd.wide_to_long(df.rename(columns={'time':'time1'}).reset_index(),
'time', i='index', j='t')
.sort_values(['time','val2'])
.drop_duplicates('time')
.dropna(subset=['time'])
.reset_index(drop=True))
output:
val1 val2 time
0 1.0 2 0.1
1 1.0 2 0.2
2 3.0 2 0.3
3 3.0 2 0.4 <- val1 incorrect
4 1.0 9 0.8
5 NaN 2 1.0
IIUC,您無法使用wide_to_long
實現此目的。
您沒有規范的重塑。 有重復的值(例如時間0.4),你需要在這里做出選擇。
因此,我想您需要執行兩次合並並按所需順序合並:
m1 = (
df[['time', 'val1']]
.merge(df[['time2', 'val2']]
.rename(columns={'time2': 'time'}),
on='time', how='outer')
.sort_values(by='time')
)
m2 = (
df[['time', 'val2']]
.merge(df[['time2', 'val1']]
.rename(columns={'time2': 'time'}),
on='time', how='outer')
.sort_values(by='time')
)
out = m1.combine_first(m2).dropna(subset='time')
output:
time val1 val2
4 0.1 1.0 2.0
0 0.2 1.0 2.0
1 0.3 3.0 2.0
2 0.4 1.0 2.0
5 0.8 1.0 9.0
6 1.0 NaN 2.0
這是另一種簡單的方法。 melt
數據,將 time1 排序在 time2 之前,如果出現重復時間,則獲取 val1 的第一行和 val2 的最后一行。
cols = ['val1', 'val2']
(df
.rename(columns={'time': 'time1'})
.melt(id_vars=cols, value_name='time')
.dropna(subset='time')
.sort_values(by=['time', 'variable'])
.groupby('time').agg({'val1': 'first', 'val2': 'last'})
.reset_index()
)
output:
time val1 val2
0 0.1 1.0 2
1 0.2 1.0 2
2 0.3 3.0 2
3 0.4 1.0 2
4 0.8 1.0 9
5 1.0 NaN 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.