用列名替换大于0的值

wvyml7n5  于 2022-09-21  发布在  其他
关注(0)|答案(3)|浏览(148)

在行和列中有ID的 Dataframe ,表示用户访问网站的次数。我想要访问网站的所有用户ID的逐日视图,这反过来由大于或等于1的所有值表示

DF

Codes  2022-09-04  2022-09-03  2022-09-02
A1AA        1           0          0
A1BB        0           0          2
A1CC        5           0          0
A2DD        0           5          0 
A1EE        0           1          0
A1AA        0           0          1

预期产量

Dates          Codes

2022-09-04     A1AA
2022-09-04     A1CC
2022-09-03     A2DD
2022-09-03     A1EE
2022-09-02     A1BB
2022-09-02     A1AA
mgdq6dx1

mgdq6dx11#

如果NA:,您可以使用:stack通过删除受益:

(df.set_index('Codes')
 .replace(0, pd.NA)
 .rename_axis(columns='Dates').stack()
 .reset_index().drop(columns=0)
)

或者使用meltloc,尽管顺序不同(如果需要,您可以使用sort_values):

df.melt('Codes', var_name='Date').loc[lambda d: d.pop('value').ne(0)]

输出:

Codes       Dates
0  A1AA  2022-09-04
1  A1BB  2022-09-02
2  A1CC  2022-09-04
3  A2DD  2022-09-03
4  A1EE  2022-09-03
5  A1AA  2022-09-02
ht4b089n

ht4b089n2#

正在做dot

s = df.set_index('Codes')
s = s.gt(0).dot(s.columns).reset_index(name='Dates')
Out[34]: 
  Codes       Dates
0  A1AA  2022-09-04
1  A1BB  2022-09-02
2  A1CC  2022-09-04
3  A2DD  2022-09-03
4  A1EE  2022-09-03
5  A1AA  2022-09-02
de90aj5v

de90aj5v3#

要使用指定的列序列和行排序(按Dates降序)获得所需的输出,您可以执行以下操作:

df = (
    ((df.set_index('Codes') != 0) @ df.columns[1:])
    .reset_index()
    .iloc[:, ::-1]
    .set_axis(['Dates','Codes'], axis=1)
    .sort_values('Dates', ascending=False, ignore_index=True) )

解释:

  • @运算符相当于DataFrame的dot()方法
  • set_index()使Codes列不会妨碍对df中剩余的列标签执行dot()
  • reset_index()Codes还原到列
  • iloc[]颠倒列顺序
  • set_axis()按照操作中指定的方式标记列
  • sort_values()将日期按降序排列。

产出:

Dates Codes
0  2022-09-04  A1AA
1  2022-09-04  A1CC
2  2022-09-03  A2DD
3  2022-09-03  A1EE
4  2022-09-02  A1BB
5  2022-09-02  A1AA

相关问题