我正在处理学校日程安排数据,我必须区分同一课程的不同课程。
如果一个不同的班级有相同的课程,这实际上是同一课程的另一个课程,需要加以区分。这意味着有一个带有会话索引的额外列。
import pandas as pd
cols = ['course', 'class_name', 'professor']
data = [ ['Math', 'X', 'Bob'],
['Math', 'X', 'Bob'],
['Math', 'Y', 'Bob'],
['English', 'Y', 'Tim'],
['English', 'X', 'Jim'],
['English', 'X', 'Jim'],
]
df = pd.DataFrame(columns=cols, data=data)
# Add session
df['session'] = '?'
print(df)
结果应该是这样的。
course class_name professor session
0 Math X Bob 0
1 Math X Bob 0
2 Math Y Bob 1
3 Eng. Y Tim 1
4 Eng. X Jim 0
5 Eng. X Jim 0
我提出了一个令人费解的程序解决方案,这样做的方式会更pandas
?
groups = df.groupby(['course', 'class_name'])
d_sessions = {}
counter = 0
pclass = ""
pcourse = ""
for m_idx in list(groups.groups):
course = m_idx[0]
class_ = m_idx[1]
if class_ != pclass:
counter += 1
if pcourse != course:
counter = 0
pclass = class_
pcourse = course
d_sessions[m_idx] = counter
df.set_index(['course', 'class_name'], inplace=True)
for k, v in d_sessions.items():
df.set_value(col='index', value=v, index=k)
df.reset_index(inplace=True)
df
答案 0 :(得分:3)
试试吧:
df['session'] = df.groupby('course')['class_name'].transform(lambda x: (~x.duplicated()).cumsum())
输出:
course class_name professor session
0 Math X Bob 1
1 Math X Bob 1
2 Math Y Bob 2
3 English Y Tim 1
4 English X Jim 2
5 English X Jim 2
答案 1 :(得分:1)
有趣的问题。
尝试制作包含所有唯一组合及其会话编号的地图。
以df导入数据(请注意,我添加了一些行来验证我的解决方案):
import pandas as pd
cols = ['course', 'class_name', 'professor']
data = [ ['Math', 'X', 'Bob'],
['Math', 'X', 'Bob'],
['Math', 'X', 'Bob'],
['Math', 'Y', 'Bob'],
['English', 'Y', 'Tim'],
['English', 'X', 'Jim'],
['English', 'X', 'Jim'],
['English', 'Z', 'Mark'],
['Chinese', 'X', 'Mark'],
['Chinese', 'X', 'Mark'],
['Chinese', 'F', 'Mark'],
]
df = pd.DataFrame(columns=cols, data=data)
然后为每个独特的课程组合创建一个地图,并为其提供会话编号。我这样做的方法是逐帧切片,然后找到本课程的唯一类值。然后为每个组合创建一个唯一的名称,并为每个会话提供唯一的会话编号(针对每个课程)。然后使用字典覆盖会话列:
def sol():
map = {}
for item in df.course.unique():
slice = df[df['course'] == item]
mapslice = dict(zip(item + slice.class_name.unique(),
list(range(len(slice.class_name.unique())))))
map.update(mapslice)
df['session'] = (df.course + df.class_name).map(map)
return df
返回样本数据:
course class_name professor session
0 Math X Bob 0
1 Math X Bob 0
2 Math X Bob 0
3 Math Y Bob 1
4 English Y Tim 0
5 English X Jim 1
6 English X Jim 1
7 English Z Mark 2
8 Chinese X Mark 0
9 Chinese X Mark 0
10 Chinese F Mark 1
然后进行快速性能检查:
%timeit sol()
3.66 ms ± 44 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
与您的解决方案(此处称为ori)相比:
%timeit ori()
4.4 ms ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
感谢您告诉我这个答案是否有用。