如何从Python datafram中行的前一个密集列读取值

2024-05-14 06:14:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有表格.csv地址:

ID,X,X_2,X_3,Rank
XJ5,30,24,37,1
XK4,20,22,20,1
XK5,33,27,38,1
XK7,22,19,22,1
XJ5,33,22,21,2
XK4,20,22,22,2
XK5,33,24,29,2
XK6,23,21,22,2
XJ5,24,22,19,3
XK4,21,20,34,3
XK5,19,22,32,3
XK6,44,24,21,3
XK7,32,21,23,3

并希望输出表:

ID,X,X_2,X_3,Rank,PrevX
XJ5,30,24,37,1,NA
XK4,20,22,20,1,NA
XK5,33,27,38,1,NA
XK7,22,19,22,1,NA
XJ5,33,22,21,2,30
XK4,20,22,22,2,20
XK5,33,24,29,2,33
XK6,23,21,22,2,NA
XJ5,24,22,19,3,33
XK4,21,20,34,3,20
XK5,19,22,32,3,33
XK6,44,24,21,3,23
XK7,32,21,23,3,NA

新的PrevX列是Rank-1行的ID的X值

到目前为止,我掌握的情况如下:

import pandas
df = pandas.read_csv('table.csv')

Tags: csvidpandas地址情况表格narank
2条回答

更新

一种方法是:

  1. 使用^{}对每个id的数据进行分组。对每个组应用以下内容:
  2. 使用^{}rank排序
  3. 创建一个临时列,其中使用^{}rank移位1
  4. 使用^{}1添加到此新列
  5. 使用^{}将此新列与rank列进行比较:如果它们相等,则指定前面的X值,否则,指定NaN
  6. 可选以匹配预期输出:

    • ^{}删除无用列
    • ^{}重置索引
    • 使用^{}rank排序。你知道吗

代码如下:

def get_previous(df):
    df = df.sort_values(by="Rank")
    df["rank_shifted"] = df.Rank.shift().add(1)
    df["PrevX"] = np.where(df.rank_shifted == df.Rank, df.X.shift(), np.NaN)
    return df

df = df.groupby('ID').apply(get_previous)
print(df)
#         ID   X  X_2  X_3  Rank  rank_shifted  PrevX
# ID
# XJ5 0  XJ5  30   24   37     1           NaN    NaN
#     3  XJ5  33   22   21     2           2.0   30.0
#     6  XJ5  24   22   19     3           3.0   33.0
# XK4 1  XK4  20   22   20     1           NaN    NaN
#     4  XK4  20   22   22     2           2.0   20.0
#     7  XK4  21   20   34     3           3.0   20.0
# XK5 2  XK5  33   27   38     1           NaN    NaN
#     5  XK5  33   24   29     2           2.0   33.0
#     8  XK5  19   22   32     3           3.0   33.0

# Match output
df = df.reset_index(drop=True).sort_values(by="Rank").drop("rank_shifted", axis=1)
print(df)
#     ID   X  X_2  X_3  Rank  PrevX
# 0  XJ5  30   24   37     1    NaN
# 3  XK4  20   22   20     1    NaN
# 6  XK5  33   27   38     1    NaN
# 1  XJ5  33   22   21     2   30.0
# 4  XK4  20   22   22     2   20.0
# 7  XK5  33   24   29     2   33.0
# 2  XJ5  24   22   19     3   33.0
# 5  XK4  21   20   34     3   20.0
# 8  XK5  19   22   32     3   33.0

原始答案

假设列组总是由3行组成,您可以使用^{}

df["PrevX"] = df.X.shift(3)
print(df)
#     ID   X  X_2  X_3  Rank  PrevX
# 0  XJ5  30   24   37     1    NaN
# 1  XK4  20   22   20     1    NaN
# 2  XK5  33   27   38     1    NaN
# 3  XJ5  33   22   21     2   30.0
# 4  XK4  20   22   22     2   20.0
# 5  XK5  33   24   29     2   33.0
# 6  XJ5  24   22   19     3   33.0
# 7  XK4  21   20   34     3   20.0
# 8  XK5  19   22   32     3   33.0

如果您不知道每个rank组的行数,可以使用^{}^{}找到它:

print(df.groupby('Rank').size())
# Rank
# 1    3
# 2    3
# 3    3

希望有帮助!你知道吗

我认为groupbyshift如下:
_在Rankgroupby并找到diff1来创建一个掩码m,以根据它们的Rank相邻的条件(秩-1)来标识哪个ID有值。秩1中的任何相同的ID都将是标志True,否则False
_groupbyIDshiftX
_最后,使用带掩码的wherem中的False翻转到NaN

m = df.groupby('ID').Rank.diff().eq(1)
df['prevX'] = df.groupby('ID').X.shift().where(m)

Out[28]:
     ID   X  X_2  X_3  Rank  prevX
0   XJ5  30   24   37     1    NaN
1   XK4  20   22   20     1    NaN
2   XK5  33   27   38     1    NaN
3   XK7  22   19   22     1    NaN
4   XJ5  33   22   21     2   30.0
5   XK4  20   22   22     2   20.0
6   XK5  33   24   29     2   33.0
7   XK6  23   21   22     2    NaN
8   XJ5  24   22   19     3   33.0
9   XK4  21   20   34     3   20.0
10  XK5  19   22   32     3   33.0
11  XK6  44   24   21     3   23.0
12  XK7  32   21   23     3    NaN

相关问题 更多 >