Python 在pandas/numpy中将数据帧值重塑为单个基
我有一个如下的数据帧Python 在pandas/numpy中将数据帧值重塑为单个基,python,pandas,numpy,Python,Pandas,Numpy,我有一个如下的数据帧 +----------+-------+-----+-------+-------+-----+ | Date | A | B | C | D | E | +----------+-------+-----+-------+-------+-----+ | 1-Jan-21 | 1,089 | | | 195 | | +----------+-------+-----+-------+-------+-
+----------+-------+-----+-------+-------+-----+
| Date | A | B | C | D | E |
+----------+-------+-----+-------+-------+-----+
| 1-Jan-21 | 1,089 | | | 195 | |
+----------+-------+-----+-------+-------+-----+
| 2-Jan-21 | 609 | 547 | 491 | 1,091 | |
+----------+-------+-----+-------+-------+-----+
| 3-Jan-21 | 1,440 | 824 | 184 | 512 | 665 |
+----------+-------+-----+-------+-------+-----+
| 4-Jan-21 | 704 | 632 | 345 | | 969 |
+----------+-------+-----+-------+-------+-----+
| 5-Jan-21 | 297 | | 1,426 | | 555 |
+----------+-------+-----+-------+-------+-----+
df = pd.DataFrame({
'Date' : ['1-Jan-21','2-Jan-21','3-Jan-21','4-Jan-21','5-Jan-21'],
'A': [1089, 609, 1440, 704, 297],
'B': [np.nan, 547, 824, 632, np.nan],
'C': [np.nan, 491, 184, 345, 1426],
'D': [195, 1091, 512, np.nan, np.nan],
'E': [np.nan, np.nan, 665, 969, 555]
})
+------+-------+-----+-------+-------+-----+
| time | A | B | C | D | E |
+------+-------+-----+-------+-------+-----+
| t-4 | 1,089 | | | | |
+------+-------+-----+-------+-------+-----+
| t-3 | 609 | | 491 | | |
+------+-------+-----+-------+-------+-----+
| t-2 | 1,440 | 547 | 184 | 195 | 665 |
+------+-------+-----+-------+-------+-----+
| t-1 | 704 | 824 | 345 | 1,091 | 969 |
+------+-------+-----+-------+-------+-----+
| t | 297 | 632 | 1,426 | 512 | 555 |
+------+-------+-----+-------+-------+-----+
我想忽略Nan
值,将所有值放在一个底部/楼层,并将Date
值重命名为t
,t-1
,t-2
等等
我期望的输出如下
+----------+-------+-----+-------+-------+-----+
| Date | A | B | C | D | E |
+----------+-------+-----+-------+-------+-----+
| 1-Jan-21 | 1,089 | | | 195 | |
+----------+-------+-----+-------+-------+-----+
| 2-Jan-21 | 609 | 547 | 491 | 1,091 | |
+----------+-------+-----+-------+-------+-----+
| 3-Jan-21 | 1,440 | 824 | 184 | 512 | 665 |
+----------+-------+-----+-------+-------+-----+
| 4-Jan-21 | 704 | 632 | 345 | | 969 |
+----------+-------+-----+-------+-------+-----+
| 5-Jan-21 | 297 | | 1,426 | | 555 |
+----------+-------+-----+-------+-------+-----+
df = pd.DataFrame({
'Date' : ['1-Jan-21','2-Jan-21','3-Jan-21','4-Jan-21','5-Jan-21'],
'A': [1089, 609, 1440, 704, 297],
'B': [np.nan, 547, 824, 632, np.nan],
'C': [np.nan, 491, 184, 345, 1426],
'D': [195, 1091, 512, np.nan, np.nan],
'E': [np.nan, np.nan, 665, 969, 555]
})
+------+-------+-----+-------+-------+-----+
| time | A | B | C | D | E |
+------+-------+-----+-------+-------+-----+
| t-4 | 1,089 | | | | |
+------+-------+-----+-------+-------+-----+
| t-3 | 609 | | 491 | | |
+------+-------+-----+-------+-------+-----+
| t-2 | 1,440 | 547 | 184 | 195 | 665 |
+------+-------+-----+-------+-------+-----+
| t-1 | 704 | 824 | 345 | 1,091 | 969 |
+------+-------+-----+-------+-------+-----+
| t | 297 | 632 | 1,426 | 512 | 555 |
+------+-------+-----+-------+-------+-----+
在
pandas
或numpy
中,我应该如何解决这个问题?您可以使用键
参数对每列的排序
,然后通过列表理解更改索引
:
df = df.set_index('Date').apply(lambda x: pd.Series(sorted(x, key=pd.notna)))
df.index = [f't-{x}' if x!=0 else 't' for x in range(len(df)-1, -1, -1)]
print (df)
A B C D E
t-4 1089 NaN NaN NaN NaN
t-3 609 NaN 491.0 NaN NaN
t-2 1440 547.0 184.0 195.0 665.0
t-1 704 824.0 345.0 1091.0 969.0
t 297 632.0 1426.0 512.0 555.0
在numpy
中,可以使用非常好的@Divakar函数:
df = df.drop('Date', axis=1)
#https://stackoverflow.com/a/44559180/2901002
df = pd.DataFrame(justify(df.to_numpy(), invalid_val=np.nan, axis=0, side='down'),
columns=df.columns)
df.index = [f't-{x}' if x!=0 else 't' for x in range(len(df)-1, -1, -1)]
print (df)
A B C D E
t-4 1089.0 NaN NaN NaN NaN
t-3 609.0 NaN 491.0 NaN NaN
t-2 1440.0 547.0 184.0 195.0 665.0
t-1 704.0 824.0 345.0 1091.0 969.0
t 297.0 632.0 1426.0 512.0 555.0
如果需要第一列时间
使用:
您可以使用
键
参数按每列的排序
,然后按列表理解更改索引
:
df = df.set_index('Date').apply(lambda x: pd.Series(sorted(x, key=pd.notna)))
df.index = [f't-{x}' if x!=0 else 't' for x in range(len(df)-1, -1, -1)]
print (df)
A B C D E
t-4 1089 NaN NaN NaN NaN
t-3 609 NaN 491.0 NaN NaN
t-2 1440 547.0 184.0 195.0 665.0
t-1 704 824.0 345.0 1091.0 969.0
t 297 632.0 1426.0 512.0 555.0
在numpy
中,可以使用非常好的@Divakar函数:
df = df.drop('Date', axis=1)
#https://stackoverflow.com/a/44559180/2901002
df = pd.DataFrame(justify(df.to_numpy(), invalid_val=np.nan, axis=0, side='down'),
columns=df.columns)
df.index = [f't-{x}' if x!=0 else 't' for x in range(len(df)-1, -1, -1)]
print (df)
A B C D E
t-4 1089.0 NaN NaN NaN NaN
t-3 609.0 NaN 491.0 NaN NaN
t-2 1440.0 547.0 184.0 195.0 665.0
t-1 704.0 824.0 345.0 1091.0 969.0
t 297.0 632.0 1426.0 512.0 555.0
如果需要第一列时间
使用:
使用简单的方法
- 每个系列
dropna()
- concat开始使系列长度一致
- 每个系列
dropna()
- concat开始使系列长度一致
这就像一个魅力,被接受和投票。但是,我无法理解
pandas
答案中的sorted
方法。即使我们正在排序,最终结果也不会排序。理解正确吗?@Tommy-它应该按键
参数排序,该参数正在测试不丢失的值,因此它应该工作正确,更多信息嗨,在第一行使用pd.Series()
方法有什么好处?答案是一样的,没有它也一样。@Tommy可以随意省略它,我认为只有旧版的熊猫才有必要。这就像一种魅力,被接受并被提升。但是,我无法理解pandas
答案中的sorted
方法。即使我们正在排序,最终结果也不会排序。理解正确吗?@Tommy-它应该按键
参数排序,该参数正在测试不丢失的值,因此它应该工作正确,更多信息嗨,在第一行使用pd.Series()
方法有什么好处?答案是一样的,没有它也一样。@Tommy可以随意省略它,我认为只有旧版本的熊猫才有必要。