0
votes

pandas pour lire un fichier texte et le convertir en colonne de la table de données CSV

J'ai un fichier test_dns où nous avons des données comme ci-dessous, cependant les données seront un peu volumineuses ci-dessous sont juste deux exemples ..

>>> for i in opened_file.read().split('\n\n'):
...     dfs.append(pd.read_fwf(StringIO(i)))
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 737, in read_fwf
    return _read(filepath_or_buffer, kwds)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 445, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 814, in __init__
    self._make_engine(self.engine)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 1055, in _make_engine
    self._engine = klass(self.f, **self.options)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 3403, in __init__
    PythonParser.__init__(self, f, **kwds)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 2070, in __init__
    self._make_reader(f)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 3407, in _make_reader
    self.comment, self.skiprows)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 3307, in __init__
    self.colspecs = self.detect_colspecs(skiprows=skiprows)
  File "/grid/common/pkgs/python/v3.6.1/lib/python3.6/site-packages/pandas/io/parsers.py", line 3366, in detect_colspecs
    raise EmptyDataError("No rows from which to infer column width")
pandas.errors.EmptyDataError: No rows from which to infer column width

I ' Je cherche à mettre les données dans le cadre de données pandas et à les colonnes plus loin en fonction de la ligne "---"

J'ai essayé ci-dessous, mais en tant qu'apprenant débutant, je cherche à me faire une idée à travers ..

---------- dns01-sh01 ---------     ---------- dns02-sh02 ---------
zone "celina.com." IN {             zone "celina.com." IN {
zone "global.celina.com." {         zone "global.celina.com." {
zone "storage.celina.com." {        zone "storage.celina.com." {
zone "gusain.com" {                 zone "gusain.com" {
zone "." IN {                       zone "." IN {
zone "10.in-addr.arpa." IN {        zone "10.in-addr.arpa." IN {
zone "99.139.in-addr.arpa." IN {    zone "99.139.in-addr.arpa." IN {
zone "190.158.in-addr.arpa." IN {   zone "190.158.in-addr.arpa." IN {
zone "172.in-addr.arpa." IN {       zone "172.in-addr.arpa." IN {
zone "localdomain." IN {            zone "localdomain." IN {
zone "localhost." IN {              zone "localhost." IN {
zone "0.0.127.in-addr.arpa." IN {   zone "0.0.127.in-addr.arpa." IN {
zone "255.in-addr.arpa." IN {       zone "255.in-addr.arpa." IN {
zone "0.in-addr.arpa." IN {         zone "0.in-addr.arpa." IN {

Résultat souhaité:

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.read_fwf("test_dns")
>>> df
      ---------- dns01-sh01 ---------
0             zone "celina.com." IN {
1         zone "global.celina.com." {
2        zone "storage.celina.com." {
3                 zone "gusain.com" {
4                       zone "." IN {
5        zone "10.in-addr.arpa." IN {
6    zone "99.139.in-addr.arpa." IN {
7   zone "190.158.in-addr.arpa." IN {
8       zone "172.in-addr.arpa." IN {
9            zone "localdomain." IN {
10             zone "localhost." IN {
11  zone "0.0.127.in-addr.arpa." IN {
12      zone "255.in-addr.arpa." IN {
13        zone "0.in-addr.arpa." IN {
14    ---------- dns02-sh02 ---------
15            zone "celina.com." IN {
16        zone "global.celina.com." {
17       zone "storage.celina.com." {
18                zone "gusain.com" {
19                      zone "." IN {
20       zone "10.in-addr.arpa." IN {
21   zone "99.139.in-addr.arpa." IN {
22  zone "190.158.in-addr.arpa." IN {
23      zone "172.in-addr.arpa." IN {
24           zone "localdomain." IN {
25             zone "localhost." IN {
26  zone "0.0.127.in-addr.arpa." IN {
27      zone "255.in-addr.arpa." IN {
28        zone "0.in-addr.arpa." IN {

Erreurs lors de l'exécution de la solution à partir de @Sandeep.

---------- dns01-sh01 ---------
zone "celina.com." IN {
zone "global.celina.com." {
zone "storage.celina.com." {
zone "gusain.com" {
zone "." IN {
zone "10.in-addr.arpa." IN {
zone "99.139.in-addr.arpa." IN {
zone "190.158.in-addr.arpa." IN {
zone "172.in-addr.arpa." IN {
zone "localdomain." IN {
zone "localhost." IN {
zone "0.0.127.in-addr.arpa." IN {
zone "255.in-addr.arpa." IN {
zone "0.in-addr.arpa." IN {

---------- dns02-sh02 ---------
zone "celina.com." IN {
zone "global.celina.com." {
zone "storage.celina.com." {
zone "gusain.com" {
zone "." IN {
zone "10.in-addr.arpa." IN {
zone "99.139.in-addr.arpa." IN {
zone "190.158.in-addr.arpa." IN {
zone "172.in-addr.arpa." IN {
zone "localdomain." IN {
zone "localhost." IN {
zone "0.0.127.in-addr.arpa." IN {
zone "255.in-addr.arpa." IN {
zone "0.in-addr.arpa." IN {


0 commentaires

3 Réponses :


1
votes

Ce n'est peut-être pas une méthode pythonique, mais vous pouvez essayer cette approche simple:

      ---------- dns01-sh01 ---------    ---------- dns02-sh02 ---------
0             zone "celina.com." IN {            zone "celina.com." IN {
1         zone "global.celina.com." {        zone "global.celina.com." {
2        zone "storage.celina.com." {       zone "storage.celina.com." {
3                 zone "gusain.com" {                zone "gusain.com" {
4                       zone "." IN {                      zone "." IN {
5        zone "10.in-addr.arpa." IN {       zone "10.in-addr.arpa." IN {
6    zone "99.139.in-addr.arpa." IN {   zone "99.139.in-addr.arpa." IN {
7   zone "190.158.in-addr.arpa." IN {  zone "190.158.in-addr.arpa." IN {
8       zone "172.in-addr.arpa." IN {      zone "172.in-addr.arpa." IN {
9            zone "localdomain." IN {           zone "localdomain." IN {
10             zone "localhost." IN {             zone "localhost." IN {
11  zone "0.0.127.in-addr.arpa." IN {  zone "0.0.127.in-addr.arpa." IN {
12      zone "255.in-addr.arpa." IN {      zone "255.in-addr.arpa." IN {
13        zone "0.in-addr.arpa." IN {        zone "0.in-addr.arpa." IN {

Sortie:

import pandas as pd

txt_file = open("test_dns",'r')
text = txt_file.read().split('\n')
cols = []
cols1 = []
cols2 = []
for txt in text:
    if "-----" in txt:
        cols.append(txt)
    elif txt == "":
        pass
    else:
        if len(cols) == 1:
            cols1.append(txt)
        else:
            cols2.append(txt)
data = ({cols[0]:cols1, cols[1]:cols2})
df = pd.DataFrame(data)
print (df)


7 commentaires

Haha, c'est pythonique mais pas forcément pandasique: P


Merci @Yusufsn pour la réponse, je suis en train de le tester, désolé pour le moment, je ne peux pas voter pour car j'ai eu deux votes contre :-)


@ user294110 Cela pourrait être bien si vous acceptez l'une des réponses.


@ user294110 Vous pouvez également voir ma réponse.


Acceptez l'une des réponses si cela vous aide. Également, votez pour les autres réponses si elles vous donnent des idées.


@Yusufsn Il n'a pas encore assez de réputation.


@ U9-Forward, je vais sûrement faire ça .. juste tester toutes les réponses et j'accepterai l'une des meilleures réponses ... je suis désolé car je n'ai pas pu voter pour cause de mauvaise réputation.



1
votes

Utilisez open avec split sur \ n \ n puis utilisez for loop et pandas.concat :

from pandas.compat import StringIO
opened_file = open("test_dns.txt",'r')

dfs = []
for i in opened_file.read().split('\n\n'):
    dfs.append(pd.read_fwf(StringIO(i)))

# Or alternative to for loop 
dfs = [pd.read_fwf(StringIO(i)) for i in opened_file.read().split('\n\n')]

df = pd.concat(dfs, axis=1)

print(df)
      ---------- dns01-sh01 ---------    ---------- dns02-sh02 ---------
0             zone "celina.com." IN {            zone "celina.com." IN {
1         zone "global.celina.com." {        zone "global.celina.com." {
2        zone "storage.celina.com." {       zone "storage.celina.com." {
3                 zone "gusain.com" {                zone "gusain.com" {
4                       zone "." IN {                      zone "." IN {
5        zone "10.in-addr.arpa." IN {       zone "10.in-addr.arpa." IN {
6    zone "99.139.in-addr.arpa." IN {   zone "99.139.in-addr.arpa." IN {
7   zone "190.158.in-addr.arpa." IN {  zone "190.158.in-addr.arpa." IN {
8       zone "172.in-addr.arpa." IN {      zone "172.in-addr.arpa." IN {
9            zone "localdomain." IN {           zone "localdomain." IN {
10             zone "localhost." IN {             zone "localhost." IN {
11  zone "0.0.127.in-addr.arpa." IN {  zone "0.0.127.in-addr.arpa." IN {
12      zone "255.in-addr.arpa." IN {      zone "255.in-addr.arpa." IN {
13        zone "0.in-addr.arpa." IN {        zone "0.in-addr.arpa." IN {


6 commentaires

Merci @Sandeep pour la réponse, je la teste.


@ user294110 Quel est le problème que vous rencontrez.


Désolé, j'ai décoché la réponse acceptée car elle ne fonctionne pas avec un ensemble de données plus volumineux et une erreur de lancement pandas.errors.EmptyDataError: Aucune ligne à partir de laquelle déduire la largeur de la colonne


@ user294110 Cela peut être utile si vous fournissez ces données d'erreur au débogage.


J'ai mis à jour le message avec les erreurs car dans la section Commentaire, ceux-ci ne peuvent pas être logés.


@ user294110 Pouvez-vous publier votre fichier de données brutes ou vos données?, cela n'aide pas à comprendre.



1
votes

Essayez ceci:

      ---------- dns01-sh01 ---------    ---------- dns02-sh02 ---------
0             zone "celina.com." IN {    ---------- dns02-sh02 ---------
1         zone "global.celina.com." {            zone "celina.com." IN {
2        zone "storage.celina.com." {        zone "global.celina.com." {
3                 zone "gusain.com" {       zone "storage.celina.com." {
4                       zone "." IN {                zone "gusain.com" {
5        zone "10.in-addr.arpa." IN {                      zone "." IN {
6    zone "99.139.in-addr.arpa." IN {       zone "10.in-addr.arpa." IN {
7   zone "190.158.in-addr.arpa." IN {   zone "99.139.in-addr.arpa." IN {
8       zone "172.in-addr.arpa." IN {  zone "190.158.in-addr.arpa." IN {
9            zone "localdomain." IN {      zone "172.in-addr.arpa." IN {
10             zone "localhost." IN {           zone "localdomain." IN {
11  zone "0.0.127.in-addr.arpa." IN {             zone "localhost." IN {
12      zone "255.in-addr.arpa." IN {  zone "0.0.127.in-addr.arpa." IN {
13        zone "0.in-addr.arpa." IN {      zone "255.in-addr.arpa." IN {

Résultat:

df2 = df.copy()
df = pd.DataFrame()
df[df2.columns[0]] = df2.iloc[:, 0][:df2.iloc[:, 0].str[0].ne('-').idxmin()]
df[df2.iloc[len(df)].item()] = df2.drop(df.index.tolist()).iloc[1:].reset_index(drop=True)
print(df)


2 commentaires

Merci à U9 - en avant pour la réponse, je le teste.


@ user294110 Après avoir accepté, vous pouvez voter, car vous aurez 16 représentants, ce qui est suffisant