我在pandas数据框中有一些看起来像这样的数据;
CAR_TYPE MILEAGE
FORD 100
FORD 100
FORD 200
FORD 300
VW 100
VW 150
VW 150
VW 300
我想“分解”数据以返回每对的唯一ID。但是我希望将独特的ID“重置”为零,以便单独制作汽车。目前我的分解使用以下内容;
df['CAR_ID']=pd.factorize(pd.lib.fast_zip([df.CAR_TYPE.values, df.MILEAGE.values]))[0]
df.CAR_ID=df[['CAR_ID', 'CAR_TYPE']].astype(str).apply(lambda x: ''.join(x), axis=1)
给我一些像
的东西CAR_TYPE MILEAGE CAR_ID
FORD 100 FORD0
FORD 100 FORD0
FORD 200 FORD1
FORD 300 FORD2
VW 100 VW3
VW 150 VW4
VW 150 VW4
VW 300 VW5
理想情况下我想
CAR_TYPE MILEAGE IDEAL_CAR_ID
FORD 100 FORD0
FORD 100 FORD0
FORD 200 FORD1
FORD 300 FORD2
VW 100 VW0
VW 150 VW1
VW 150 VW1
VW 300 VW2
对于相对愚蠢的问题道歉,经过漫长的一天后,他的斗智斗勇。我知道它可以用stack / unstack,reset_index / set_index来解决。
答案 0 :(得分:3)
如果MILEAGE
中的值按群组排序,则可以groupby
与rank
一起使用:
a = df.groupby(['CAR_TYPE'])['MILEAGE'].rank(method='dense') \
.sub(1).astype(int).astype(str)
df['IDEAL_CAR_ID'] = df['CAR_TYPE'].add(a)
print (df)
CAR_TYPE MILEAGE IDEAL_CAR_ID
0 FORD 100 FORD0
1 FORD 100 FORD0
2 FORD 200 FORD1
3 FORD 300 FORD2
4 VW 100 VW0
5 VW 150 VW1
6 VW 150 VW1
7 VW 300 VW2
factorize
的另一个解决方案:
a = df.groupby(['CAR_TYPE'])['MILEAGE'] \
.transform(lambda x: pd.factorize(x)[0]).astype(str)
df['IDEAL_CAR_ID'] = df['CAR_TYPE'].add(a)
print (df)
CAR_TYPE MILEAGE IDEAL_CAR_ID
0 FORD 100 FORD0
1 FORD 100 FORD0
2 FORD 200 FORD1
3 FORD 300 FORD2
4 VW 100 VW0
5 VW 150 VW1
6 VW 150 VW1
7 VW 300 VW2
如果列未排序,则输出不同:
print (df)
CAR_TYPE MILEAGE
0 FORD 500
1 FORD 500
2 FORD 200
3 FORD 300
4 VW 100
5 VW 150
6 VW 150
7 VW 300
a = df.groupby(['CAR_TYPE'])['MILEAGE'].rank(method='dense') \
.sub(1).astype(int).astype(str)
df['IDEAL_CAR_ID'] = df['CAR_TYPE'].add(a)
print (df)
CAR_TYPE MILEAGE IDEAL_CAR_ID
0 FORD 500 FORD2
1 FORD 500 FORD2
2 FORD 200 FORD0
3 FORD 300 FORD1
4 VW 100 VW0
5 VW 150 VW1
6 VW 150 VW1
7 VW 300 VW2
a = df.groupby(['CAR_TYPE'])['MILEAGE'] \
.transform(lambda x: pd.factorize(x)[0]).astype(str)
df['IDEAL_CAR_ID'] = df['CAR_TYPE'].add(a)
print (df)
CAR_TYPE MILEAGE IDEAL_CAR_ID
0 FORD 500 FORD0
1 FORD 500 FORD0
2 FORD 200 FORD1
3 FORD 300 FORD2
4 VW 100 VW0
5 VW 150 VW1
6 VW 150 VW1
7 VW 300 VW2
答案 1 :(得分:2)
或者你可以试试这个。
{{1}}
答案 2 :(得分:2)
f1 = pd.factorize(list(zip(df.CAR_TYPE.values, df.MILEAGE.values)))[0]
f0 = pd.factorize(df.CAR_TYPE.values)[0] \
* (df.groupby('CAR_TYPE').CAR_TYPE.transform('count').values - 1)
df.assign(CAR_ID=df.CAR_TYPE.add((f1 - f0).astype(str)))
CAR_TYPE MILEAGE CAR_ID
0 FORD 100 FORD0
1 FORD 100 FORD0
2 FORD 200 FORD1
3 FORD 300 FORD2
4 VW 100 VW0
5 VW 150 VW1
6 VW 150 VW1
7 VW 300 VW2
答案 3 :(得分:0)
这也可以通过使用groupby.ngroup()
并使用.astype(str)
转换为字符串,然后使用series.radd()
将其添加到CAR_TYPE
列来实现:
df['CAR_ID'] = (df.groupby(['CAR_TYPE','MILEAGE'],sort=False).ngroup()
.astype(str).radd(df['CAR_TYPE']))
print(df)
CAR_TYPE MILEAGE CAR_ID
0 FORD 100 FORD0
1 FORD 100 FORD0
2 FORD 200 FORD1
3 FORD 300 FORD2
4 VW 100 VW3
5 VW 150 VW4
6 VW 150 VW4
7 VW 300 VW5
有关更多详细信息,请参见以下ngroup
产生的内容:
print(df.groupby(['CAR_TYPE','MILEAGE'],sort=False).ngroup())
0 0
1 0
2 1
3 2
4 3
5 4
6 4
7 5