假设我有这个数据框。
df = pd.DataFrame([['A-store',5,'B-store',4,'C-store',6], \
['B-store',3,'P-store',4,np.nan,np.nan], \
['N-store',20,np.nan,np.nan,'I-store',9], \
['L-store',8,'N-store',2,'A-store',5]],
columns=['store_1','time_1','store_2','time_2','store_3','time_3'])
store_1 time_1 store_2 time_2 store_3 time_3
0 A-store 5 B-store 4.0 C-store 6.0
1 B-store 3 P-store 4.0 NaN NaN
2 N-store 20 NaN NaN I-store 9.0
3 L-store 8 N-store 2.0 A-store 5.0
例如:要到达A商店,需要5分钟。
如何对一组值(存储,时间)进行排序,以使最左边的一组变得最短,最右边的一组变得最长。我需要在多列上对一组值进行排序。此外,它还包含NaN。
这是理想的输出。
shorter <-----------------------------------> longer
store_1 time_1 store_2 time_2 store_3 time_3
0 B-store 4.0 A-store 5 C-store 6.0
1 B-store 3 P-store 4.0 NaN NaN
2 I-store 9.0 N-store 20 NaN NaN
3 N-store 2.0 A-store 5.0 L-store 8
我可能会旋转或堆叠,然后按行排序。但是,我不确定该怎么做。
如果有人有什么好主意或代码,请告诉我。
谢谢!
答案 0 :(得分:3)
想法是使用Series.str.split
和DataFrame.stack
重塑值,然后按第一级和time
列排序,按GroupBy.cumcount
创建新顺序,最后重塑为原始值:< / p>
df.columns = df.columns.str.split('_', expand=True)
df1=df.stack().reset_index(level=1,drop=True).rename_axis('lvl1').sort_values(['lvl1','time'])
df1 = df1.set_index(df1.groupby(level=0).cumcount().add(1), append=True)
df1 = df1.unstack().sort_index(axis=1, level=1).rename_axis(None)
df1.columns = [f'{a}_{b}' for a, b in df1.columns]
print (df1)
store_1 time_1 store_2 time_2 store_3 time_3
0 B-store 4.0 A-store 5.0 C-store 6.0
1 B-store 3.0 P-store 4.0 NaN NaN
2 I-store 9.0 N-store 20.0 NaN NaN
3 N-store 2.0 A-store 5.0 L-store 8.0
答案 1 :(得分:1)
这可能是更长的方法。也许有人可以给您更好的方法。但这会提供您需要的输出。
import pandas as pd
import numpy as np
import operator
def func(lst):
d = ({lst[i]: lst[i + 1] for i in range(0, len(lst), 2)})
d = sorted(d.items(), key=operator.itemgetter(1))
return [val for sublist in d for val in sublist]
df = pd.DataFrame([['A-store',5,'B-store',4,'C-store',6], \
['B-store',3,'P-store',4,np.nan,np.nan], \
['N-store',20,np.nan,np.nan,'I-store',9], \
['L-store',8,'N-store',2,'A-store',5]],
columns=['store_1','time_1','store_2','time_2','store_3','time_3'])
pd.DataFrame.from_records(df.apply(lambda x : func(x),axis=1) columns=['store_1','time_1','store_2','time_2','store_3','time_3'],
)
这将返回以下内容作为输出。
store_1 time_1 store_2 time_2 store_3 time_3
0 B-store 4.0 A-store 5.0 C-store 6.0
1 B-store 3.0 P-store 4.0 NaN NaN
2 N-store 20.0 NaN NaN I-store 9.0
3 N-store 2.0 A-store 5.0 L-store 8.0