Je lis un fichier xls et je le convertis en fichier csv dans des databricks en utilisant pyspark. Mes données d'entrée sont au format de chaîne 101101114501700 dans le fichier xls. Mais après l'avoir converti au format CSV à l'aide de pandas et écrit dans le dossier datalake, mes données s'affichent sous la forme 101101114501700.0. Mon code est donné ci-dessous. S'il vous plaît, aidez-moi pourquoi je reçois la partie décimale dans les données.

for file in os.listdir("/path/to/file"):
     if file.endswith(".xls"):
       filepath = os.path.join("/path/to/file",file)         
       filepath_pd = pd.ExcelFile(filepath)
       names = filepath_pd.sheet_names        
       df = pd.concat([filepath_pd.parse(name) for name in names])        
       df1 = df.to_csv("/path/to/file"+file.split('.')[0]+".csv", sep=',', encoding='utf-8', index=False)
       print(time.strftime("%Y%m%d-%H%M%S") + ": XLS files converted to CSV and moved to folder"
0
pythonUser 19 mars 2019 à 11:04

2 réponses

Meilleure réponse

Votre question n'a rien à voir avec Spark ou PySpark. C'est lié aux Pandas.

En effet, les Pandas interprètent et déduisent automatiquement le type de données des colonnes. Étant donné que toutes les valeurs de votre colonne sont numériques, Pandas la considérera comme un type de données float.

Pour éviter cela, La méthode pandas.ExcelFile.parse accepte un argument appelé converters, vous pouvez l'utiliser pour indiquer aux Pandas le type de données de colonne spécifique en :

# if you want one specific column as string
df = pd.concat([filepath_pd.parse(name, converters={'column_name': str}) for name in names])

OU

# if you want all columns as string
# and you have multi sheets and they do not have same columns
# this merge all sheets into one dataframe
def get_converters(excel_file, sheet_name, dt_cols):
    cols = excel_file.parse(sheet_name).columns
    converters = {col: str for col in cols if col not in dt_cols}
    for col in dt_cols:
        converters[col] = pd.to_datetime
    return converters

df = pd.concat([filepath_pd.parse(name, converters=get_converters(filepath_pd, name, ['date_column'])) for name in names]).reset_index(drop=True)

OU

# if you want all columns as string
# and all your sheets have same columns
cols = filepath_pd.parse().columns
dt_cols = ['date_column']
converters = {col: str for col in cols if col not in dt_cols}
for col in dt_cols:
    converters[col] = pd.to_datetime
df = pd.concat([filepath_pd.parse(name, converters=converters) for name in names]).reset_index(drop=True)
0
Yuan JI 19 mars 2019 à 14:16

Je pense que le champ est automatiquement analysé comme flottant lors de la lecture de l'excel. Je le corrigerais après:

df['column_name'] = df['column_name'].astype(int)

Si votre colonne contient des valeurs nulles, vous ne pouvez pas convertir en nombre entier, vous devrez donc d'abord remplir les valeurs nulles:

df['column_name'] = df['column_name'].fillna(0).astype(int)

Ensuite, vous pouvez concaténer et stocker la façon dont vous le faisiez

2
gilgorio 19 mars 2019 à 08:54