簡體   English   中英

使用 wide_to_long 將多個時間列合並為一個列

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM