Как создать новые столбцы на основе нескольких условий в других столбцах, используя цикл for? - PullRequest
0 голосов
/ 09 марта 2019

Я пытаюсь написать цикл for, который создает новые столбцы с логическими значениями, указывающими, содержат ли оба столбца, на которые ссылаются, истинные значения. Я бы хотел, чтобы этот цикл проходил через существующие столбцы и сравнивал, но я не уверен, как заставить цикл делать это. До сих пор я пытался использовать списки, которые ссылаются на разные столбцы. Код следует:

import pandas as pd
import numpy as np

elig = pd.read_excel('spreadsheet.xlsx')

elig['ELA'] = elig['SELECTED_EXAMS'].str.match('.*English Language Arts.*')
elig['LivEnv'] = elig['SELECTED_EXAMS'].str.match('.*Living Environment.*')
elig['USHist'] = elig['SELECTED_EXAMS'].str.match('.*US History.*')
elig['Geometry'] = elig['SELECTED_EXAMS'].str.match('.*Geometry.*')
elig['AlgebraI'] = elig['SELECTED_EXAMS'].str.match('.*Algebra I.*')
elig['GlobalHistory'] = elig['SELECTED_EXAMS'].str.match('.*Global History.*')
elig['Physics'] = elig['SELECTED_EXAMS'].str.match('.*Physics.*')
elig['AlgebraII'] = elig['SELECTED_EXAMS'].str.match('.*Algebra II.*')
elig['EarthScience'] = elig['SELECTED_EXAMS'].str.match('.*Earth Science.*')
elig['Chemistry'] = elig['SELECTED_EXAMS'].str.match('.*Chemistry.*')
elig['LOTE Spanish'] = elig['SELECTED_EXAMS'].str.match('.*LOTE – Spanish.*')

# CHANGE TO LOOP--enter columns for instances in which scorers overlap competencies (e.g. can score two different exams). This is helpful in the event that two exams are scored on the same day, and we need to resolve numbers of scorers.

exam_list = ['ELA','LiveEnv','USHist','Geometry','AlgebraI','GlobalHistory','Physics','AlgebraII','EarthScience','Chemistry','LOTE Spanish']
nestedExam_list = ['ELA','LiveEnv','USHist','Geometry','AlgebraI','GlobalHistory','Physics','AlgebraII','EarthScience','Chemistry','LOTE Spanish']

for exam in exam_list:
    for nestedExam in nestedExam_list:
        elig[exam+nestedExam+' Overlap'] = np.where((elig[exam]==True)&(elig[nestedExam]==True,),True,False)

Я думаю, что проблема связана с np.where (), где я хочу, чтобы экзамен и nestedExam вызывали соответствующие столбцы, но вместо этого они просто вызывают элементы списка. Сообщение об ошибке следующее:


ValueError                                Traceback (most recent call last)
<ipython-input-33-9347975b8865> in <module>
      3 for exam in exam_list:
      4     for nestedExam in nestedExam_list:
----> 5         elig[exam+nestedExam+' Overlap'] = np.where((elig[exam]==True)&(elig[nestedExam]==True,),True,False)
      6 
      7 """

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\ops.py in wrapper(self, other)
   1359 
   1360             res_values = na_op(self.values, other)
-> 1361             unfilled = self._constructor(res_values, index=self.index)
   1362             return filler(unfilled).__finalize__(self)
   1363 

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\series.py in __init__(self, data, index, dtype, name, copy, fastpath)
    260                             'Length of passed values is {val}, '
    261                             'index implies {ind}'
--> 262                             .format(val=len(data), ind=len(index)))
    263                 except TypeError:
    264                     pass

ValueError: Length of passed values is 1, index implies 26834

Может ли кто-нибудь помочь мне с этим?

1 Ответ

0 голосов
/ 09 марта 2019

Сначала вы пройдете свои комбинации более эффективно, и без двойного счета я мог бы порекомендовать вам использовать встроенную библиотеку itertools .

`import itertools

exam_list = ['A', 'B', 'C', 'D']
for exam1, exam2 in itertools.combinations(exam_list, 2):
    print(exam1 + '_' + exam2)
A_B
A_C
A_D
B_C
B_D
C_D

Если вам действительно нужны все возможные ордера / комбинации, вы можете заменить permutations на combinations

Чтобы справиться с реальной проблемой, вам нужно гораздо меньше кода, чтобы делать то, что вы хотите. Если у вас есть два столбца elig[exam1] и elig[exam2], которые оба являются логическими массивами, то массив, в котором оба имеют значение true, равен (elig[exam1] & elig[exam2]). Это называется «побитовой» или «логической и» операцией.

Например:

df = pd.DataFrame({'A': ['car', 'cat', 'hat']})
df['start=c'] = df['A'].str.startswith('c')
df['end=t'] = df['A'].str.endswith('t')
df['both'] = df['start=c'] & df['end=t']
     A  start=c  end=t   both
0  car     True  False  False
1  cat     True   True   True
2  hat    False   True  False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...