Ошибка типа: объект ‘int’ не поддается подписке при чтении из HDFS

#python #hadoop #hdfs

#python #hadoop #hdfs

Вопрос:

Я читаю в файле из HDFS и продолжаю получать эту ошибку: TypeError: 'int' object is not subscriptable

файл csv:

 CLAIM_NUM,BEN_ST,AGE,MEDICAL_ONLY_IND,TTL_MED_LOSS,TTL_IND_LOSS,TTL_MED_EXP,TTL_IND_EXP,BP_CD,NI_CD,legalrep,depression,cardiac,diabetes,hypertension,obesity,smoker,subabuse,arthritis,asthma,CPT_codes,D,P,NDC_codes
123456789,IL,99,1,2201.26,0,97.16,0,31,4,1,0,0,0,0,0,0,0,0,0,NA,8409~71941,NA,NA
987654321,AL,98,1,568.12,0,20.82,0,42,52,1,0,0,0,0,0,0,0,0,0,NA,7242~8472~E9273,NA,NA
 

Мой код:

 with hdfs.open("/user/ras.csv") as f: 
    reader = f.read()
    
    for i, row in enumerate(reader, start=1):
        root = ET.Element('cbcalc')
        icdNode = ET.SubElement(root, "icdcodes")
        
        for code in row['D'].split('~'):
            ET.SubElement(icdNode, "code").text = code
        ET.SubElement(root, "clientid").text = row['CLAIM_NUM']
        ET.SubElement(root, "state").text = row['BEN_ST']
        ET.SubElement(root, "country").text = "US"  
        ET.SubElement(root, "age").text = row['AGE']
        ET.SubElement(root, "jobclass").text = "1" 
        ET.SubElement(root, "fulloutput").text ="Y"
        
        cfNode = ET.SubElement(root, "cfactors")
        for k in ['legalrep', 'depression', 'diabetes',
                 'hypertension', 'obesity', 'smoker', 'subabuse']:
            ET.SubElement(cfNode, k.lower()).text = str(row[k])
        
        psNode = ET.SubElement(root, "prosummary")
        
        psicdNode = ET.SubElement(psNode, "icd")
        for code in row['P'].split('~'):
            ET.SubElement(psNode, "code").text = code
            
        psndcNode = ET.SubElement(psNode, "ndc")
        for code in row['NDC_codes'].split('~'):
            ET.SubElement(psNode, "code").text = code 

        cptNode = ET.SubElement(psNode, "cpt")
        for code in row['CPT_codes'].split('~'):
            ET.SubElement(cptNode, "code").text = code

        ET.SubElement(psNode, "hcpcs")
        
        doc = ET.tostring(root, method='xml', encoding="UTF-8")
        
        response = requests.post(target_url, data=doc, headers=login_details)
        response_data = json.loads(response.text)
        if type(response_data)==dict and 'error' in response_data.keys():
            error_results.append(response_data)
        else:
            api_results.append(response_data)
 

Что мне нужно изменить, чтобы я мог перебирать csv-файл и переводить данные в формат xml для выполнения моего вызова API?

Я протестировал этот код на python, и, похоже, он работает, но как только я помещаю свой файл HDFS, он начинает падать.

Комментарии:

1. Может быть, потому, что заголовок не читается читателем? Откуда вы получаете сообщение об ошибке?

2. @Stefan он действительно читает заголовок этого файла. Не уверен, как справиться с этим изменением.

3. Можете ли вы обновить вопрос, чтобы включить полное сообщение об ошибке (в частности, включая номер строки)? Первое, что нужно попробовать, это угадать, какая переменная ошибочно является an int , и распечатать ее (или, лучше, какой-то ее родительский элемент).

4. Если вы хотите пропустить заголовок и reader фактически перебираете строки, а не символы в файле, просто добавьте next(reader) перед перечислением или используйте обычный цикл, потому что вы никогда не используете i

5. @ShapeOfMatter hdfs поступает из импорта inport pydoop.hdfs as hdfs вот документация [ crs4.github.io/pydoop/api_docs/hdfs_api.html ] и int он падает на цикл for

Ответ №1:

Проблема в том (вероятно, у меня не установлена эта библиотека), которая f.read() возвращает объект bytes. Если вы выполните итерацию по нему (используя enumerate , например), вы будете проверять int s (по одному на символ файла, в зависимости от контекста), а не какие-либо структурированные объекты «строки».

Перед запуском цикла, который вы хотите написать, необходима дополнительная обработка.

Что-то вроде этого может делать то, что вы хотите:

 import pydoop.hdfs as hdfs
from io import TextIOWrapper
from csv import DictReader

with hdfs.open("/user/ras.csv") as h,
     TextIOWrapper(h, *unknown_settings) as w,
     DictReader(w, *defaults_are_probably_ok) as dict_reader:
    for row in dict_reader:
        ...
 

Комментарии:

1. Какими должны быть unknown_settings и defaults_are_ok?

2. Обе функции / конструкторы классов принимают дополнительные необязательные аргументы; не зная всей вашей ситуации, я не уверен, что вы захотите туда передать. Оба модуля находятся в стандартной библиотеке python; проверьте документацию для этих конкретных функций и выясните, нужно ли переопределять какие-либо значения по умолчанию.