У меня есть таблица csv
из формы Google для отчета о посещаемости. Данные выглядят так
df1= pd.read_csv("12-9-2020.csv")
df1
Name StudentID
Robert C 102
Jessica Myla 103
Nana D 105
df2= pd.read_csv("12-10-2020.csv")
df2
Name StudentID
J Myla 103
Harris Kurt 104
Nana Duncan 105
У меня есть много таблиц, которые я хочу составить отчет о посещаемости компиляции. Базовый отчет о посещаемости компиляции выглядит следующим образом:
df_Basic
Name StudentID 12/9/2020 12/10/2020
Robert Case 102 0 0
Jessica Myla 103 0 0
Harris Kurt 104 0 0
Nana Duncan 105 0 0
Я хочу ввести форму данных df1, df2
в отчет о посещаемости компиляции. Если учащийся посещает занятие, оно должно быть равно 1, а заклинание имени учащегося будет соответствовать формату отчета о посещаемости компиляции.
Желаемый результат выглядит следующим образом:
df_Result
Name StudentID 12/9/2020 12/10/2020
Robert Case 102 1 0
Jessica Myla 103 1 1
Harris Kurt 104 0 1
Nana Duncan 105 1 1
Спасибо за помощь
Вероятно, вы можете сделать это с помощью
df1= pd.read_csv("12-9-2020.csv")
df1
Name StudentID
Robert C 102
Jessica Myla 103
Nana D 105
df2= pd.read_csv("12-10-2020.csv")
# get ids from second table
ids_of_presenties = df2['StudentID'].values.tolist()
# in first dataframe create a date column
current_date = '12/9/2020'
df1[current_date] = 0
df1[df1['StudentID'].isin(ids_of_presenties)][current_date] = 1 # mark the attendance of the only student present.
Нет вашего фрейма данных. надеюсь, это хорошо
Вот решение для двух фреймов данных:
df1.set_index('StudentID', inplace=True)
df1.loc[:, '12-9-2020.csv'] = 1
df2.set_index('StudentID', inplace=True)
df2.loc[:, '12-10-2020.csv'] = 1
df1 = df1.join(df2, how='outer', rsuffix='_')
df1['Name'] = df1['Name'].combine_first(df1['Name_'])
df1.drop('Name_', axis=1, inplace=True)
df1.fillna(0).reset_index()
Для большего количества кадров данных повторите строки 3–7 по мере необходимости.
Опечатка. Это должно было быть df1
.
Вот полное решение:
df
- динамически считывать все файлы в один фрейм данных из определенной папки на вашем рабочем столе (и создавать столбец Date
с assign
и получать дату из имени файла). ВЫ должны указать это в переменной files
df_attendance
- с .groupby
вернуть 1
или 0
на StudentID
и поставить Date
на столбцыdf_names
- Нормализуйте Name
данные, выбрав самое длинное имя на ID
в качестве Name
df_attendance
- join
два фрейма данных df_attendance
и df_names
import glob
files = glob.glob(r'Desktop\Students\*.csv')
df = pd.concat([pd.read_csv(f).assign(Date=pd.to_datetime(os.path.basename(f)[:-4]))
for f in files])
df_attendance = (df.groupby(['StudentID', df['Date'].dt.date]).size()
.unstack(1).fillna(0).astype(int))
df_names = (df.groupby(['StudentID'])['Name'].apply(list)
.apply(lambda x: [y for y in x if len(y) ==
max([len(z) for z in x])][0])).to_frame() # this reads.. per student choose the name that is the longest name
df_Result = df_names.join(df_attendance).reset_index()
df_Result
Out[1]:
StudentID Name 2020-12-09 2020-12-10
0 102 Robert C 1 0
1 103 Jessica Myla 1 1
2 104 Harris Kurt 0 1
3 105 Nana Duncan 1 1
Если вы хотите изменить формат дат в столбце даты, вы можете запустить приведенный ниже код, который очень похож:
files = glob.glob(r'Desktop\Students\*.csv')
df = pd.concat([pd.read_csv(f).assign(Date=pd.to_datetime(os.path.basename(f)[:-4]))
for f in files]).sort_values(['StudentID', 'Date'])
df_attendance = (df.groupby(['StudentID', df['Date'].dt.strftime('%m/%d/%y')], sort=False).size()
.unstack(1).fillna(0).astype(int))
df_names = (df.groupby(['StudentID'])['Name'].apply(list)
.apply(lambda x: [y for y in x if len(y) ==
max([len(z) for z in x])][0])).to_frame()
df_Result = df_names.join(df_attendance).reset_index()
df_Result
Out[2]:
StudentID Name 12/09/20 12/10/20
0 102 Robert C 1 0
1 103 Jessica Myla 1 1
2 104 Harris Kurt 0 1
3 105 Nana Duncan 1 1
Согласно вашему комментарию, вы можете сделать что-то вроде этого. Обратите внимание, что ЛУЧШЕ использовать StudentID вместо имени для прямого соответствия, поэтому просто замените «StudentID» на «Name», если вы используете это:
df_list = pd.read_csv(file) # pass the filepath of you file and must have column "Name:
df_list = df_list[~(df_list['Name'].isin(df_Result['Name']))] #find students not in the file
df_Result = pd.concat([df_Result, df_list[['Name']]]).fillna(0)
df_Result
Спасибо за ваш ответ. @david Как насчет того, если есть студент, который никогда не заполнял форму Google, однако его или ее имя существует в базовом отчете о посещаемости компиляции. Его или ее имени не будет в конце сводного отчета о посещаемости.
Привет @Arief, это дополнительная проблема, но см. нижнюю часть моего ответа. Если вам нужна дополнительная информация, пожалуйста, создайте новый вопрос stackoverflow и верните этот вопрос к этому, и я или кто-то другой сможет ответить.
Спасибо, у меня ошибка - имя "сустав" не определено -