我有一个熊猫数据帧:
import pandas as pd
e = [{'E1': 'A', 'E2': 'B', 'E3': 'C', 'EDAY1': 0, 'EDAY2': 1, 'EDAY3': 2}, {'E1': 'B', 'E2': '0', 'E3': '0', 'EDAY1': 2, 'EDAY2': -1, 'EDAY3': -1}, {'E1': 'F', 'E2': 'A', 'E3': 'D', 'EDAY1': 5, 'EDAY2': 5, 'EDAY3': 2}]
df = pd.DataFrame(e)
display(df)
输出:
E1 E2 E3 EDAY1 EDAY2 EDAY3
0 A B C 0 1 2
1 B 0 0 2 -1 -1
2 F A D 5 5 2
其中,E1
到E3
是事件,EDAY1
到EDAY3
是相应事件发生的日期。注意:
- 如果未发生事件,则将其标记为"0",并将相应的
EDAY
设置为-1
- 事件
E1
的优先级高于E2
,事件E2
的优先级高于事件E3
- 事件优先级与
EDAY
不对应(请参阅最后一行( - 一些事件发生在同一天
我想根据以下标准将这些事件转换为10个字符长的字符串:
- 字符串中的每个字符位置大致对应于事件发生的日期
- 没有事件的天数将由字符"0"表示
- 同一天发生的事件将按优先级排序,并立即相邻设置(我知道这不是一个完美的表示,但目前可以(
因此,在上面的例子中,我希望有以下表示:
E1 E2 E3 EDAY1 EDAY2 EDAY3 E_STR
0 A B C 0 1 2 ABC0000000
1 B 0 0 2 -1 -1 00B0000000
2 F A D 5 5 2 00D00FA000
请注意,这不是家庭作业,但我是Python和Pandas的新手,这让我很困惑。
请分享我对这个问题的看法,我使用wide_to_long
来压平原始数据帧,然后将-1和zip
所有的值排除在list
的list
中,结构不好,但不用担心,我们只需要它创建一对值和位置(在我的理解中,EDAY是E中字符的位置(
newdf=pd.wide_to_long(df.reset_index(),['E','EDAY'],i='index',j='drop').loc[lambda x : x.EDAY!=-1]
newdf.EDAY+=newdf.groupby(['index','EDAY']).cumcount()# here is to protect when two position show up same time
newdf=newdf.groupby(level=0).agg(list)
在整形之后,我们使用for循环来创建您需要的字符
l=[]
for x ,y in zip(newdf.E,newdf.EDAY):
xvar=list('0000000000')
for idx,z in enumerate(y):
xvar[z]=x[idx]
l.append(''.join(xvar))
l
Out[111]: ['ABC0000000', '00B0000000', '00D00FA000']