web-dev-qa-db-fra.com

Python/Pandas - Interface graphique permettant d'afficher un DataFrame ou une matrice

J'utilise le paquet Pandas et il crée un objet DataFrame, qui est essentiellement une matrice étiquetée. J'ai souvent des colonnes qui ont de longs champs de chaîne, ou des données avec beaucoup de colonnes, de sorte que la simple commande print ne fonctionne pas bien. J'ai écrit des fonctions de sortie texte, mais elles ne sont pas géniales.

Ce que je voudrais vraiment, c’est une interface graphique simple qui me permet d’interagir avec une structure de données, une matrice ou une table. Tout comme vous le trouverez dans un outil SQL. Fondamentalement, une fenêtre qui a une feuille de calcul en lecture seule comme vue dans les données. Je peux développer des colonnes, des pages vers le haut ou le bas, de longues tables, etc.

Je soupçonne que quelque chose comme cela existe, mais je dois googler avec les mauvais termes. Ce serait bien s'il s'agissait de pandas spécifiques, mais je suppose que je pourrais utiliser n'importe quel outil acceptant la matrice. (BTW - je suis sur Windows.)

Des pointeurs?

Ou, inversement, si quelqu'un connaît bien cet espace et sait que celui-ci n'existe probablement pas, avez-vous des suggestions quant à l'existence d'un simple cadre/widget graphique que je pourrais utiliser pour lancer le mien? (Mais étant donné que mes besoins sont limités, je suis réticent à devoir apprendre un grand framework d'interface graphique et à coder pour cette pièce.)

48
Ross R

J'utilise QTableWidget de PyQt pour afficher un DataFrame. Je crée un QTableWidgetObject et le renseigne avec QTableWidgetItems créé avec les DataFrame valeurs . Voici l'extrait de code qui lit un fichier CSV, crée un DataFrame, puis l'affiche dans une interface graphique:

df  = read_csv(filename, index_col = 0,header = 0)
self.datatable = QtGui.QTableWidget(parent=self)
self.datatable.setColumnCount(len(df.columns))
self.datatable.setRowCount(len(df.index))
for i in range(len(df.index)):
    for j in range(len(df.columns)):
        self.datatable.setItem(i,j,QtGui.QTableWidgetItem(str(df.iget_value(i, j))))

Mettre à jour:

Comme cette réponse était assez ancienne, elle mérite une mise à jour. Il existe de nombreuses options disponibles pour afficher les images dans l'interface graphique.

  1. Comme d'autres l'ont souligné, les IDE Python tels que Spyder Sont fournis avec des visualiseurs de cadres de données.
  2. qgrid est une autre option pour le widget cahier jupyter qui restitue les images dans le cahier.

Si quelqu'un souhaite toujours coder une interface graphique simple pour afficher les images dans Jupyter, voici l'exemple complet et minimal à l'aide de Pyqt5. 

%gui qt5 
from PyQt5.QtWidgets import QWidget,QScrollArea, QTableWidget, QVBoxLayout,QTableWidgetItem
import pandas as pd

win = QWidget()
scroll = QScrollArea()
layout = QVBoxLayout()
table = QTableWidget()
scroll.setWidget(table)
layout.addWidget(table)
win.setLayout(layout)    


df = pd.DataFrame({"a" : [4 ,5, 6],"b" : [7, 8, 9],"c" : [10, 11, 12]},index = [1, 2, 3])
table.setColumnCount(len(df.columns))
table.setRowCount(len(df.index))
for i in range(len(df.index)):
    for j in range(len(df.columns)):
        table.setItem(i,j,QTableWidgetItem(str(df.iloc[i, j])))

win.show()

 enter image description here

14
user1319128

Je n'étais pas entièrement satisfait de certaines autres interfaces graphiques, alors j'ai créé la mienne, que je gère maintenant sur Github Exemple:

enter image description here

Outre la fonctionnalité de base table + plot, je souhaitais disposer d'un moyen spécifique pour filtrer les données:

  • sélectionner une colonne à filtrer dans une liste déroulante
  • écrivez une "expression de soulignement" pour filtrer sur cette colonne en utilisant du code Python arbitraire. Par exemple: _ > 0 pour filtrer uniquement les valeurs positives, ou des expressions plus complexes telles que (_ >= date(2016, 1, 1)) & (_ <= date(2016, 1, 31)) par ex. pour les colonnes datetime.
33
bluenote10

La question était post en 2012 et d'autres réponses peuvent être trop vieux pour appliquer.

La réponse en 2016 est que nous devrions utiliser Pycharm et qu'il est livré avec le visualiseur DataFrame.

enter image description here

 enter image description here

12
guo

Pandas 0.13 fournit à titre expérimental:

Prise en charge PySide pour les qtpandas DataFrameModel et DataFrameWidget

voir https://github.com/pydata/pandas/blob/master/doc/source/faq.rst

vous pouvez ajouter cette fonctionnalité en utilisant

from pandas.sandbox.qtpandas import DataFrameModel, DataFrameWidget
11
working4coins

Vous pouvez utiliser la méthode to_html () dataframe pour convertir le dataframe en HTML et l’afficher dans votre navigateur. Voici un exemple en supposant que vous ayez un cadre de données appelé df. Vous devriez consulter la documentation pour voir quelles autres options sont disponibles dans la méthode to_html ().

# Format floating point numbers with 2 decimal places.
data_table = df.to_html(float_format=lambda x: '%6.2f' % x,
    classes="table display")
# The to_html() method forces a html table border of 1 pixel.
# I use 0  in my table so I  change the html, since there is no 
# border argument in the to_html() method.
data_table = data_table.replace('border="1"','border="0"')
# I alson like to display blanks instead on nan.
data_table = data_table.replace('nan', '')

Si vous voulez que la table soit bien formatée et que vous puissiez la faire défiler, vous pouvez utiliser le plug-in datatables pour jQuery www.datatables.net . Voici le code javascript que j’utilise pour afficher un tableau des parchemins dans les deux directions x et y.

$('.table').dataTable({
    "bPaginate": true,
    "bLengthChange": true,
    "bSort": false,
    "bStateSave": true,
    "sScrollY": 900,
    "sScrollX": 1000,
    "aLengthMenu": [[50, 100, 250, 500, 1000, -1], [50, 100, 250, 500, 1000, "All"]],
    "iDisplayLength": 100,
});
8
Yofe

En plus de toutes les réponses utiles, je voudrais mentionner que le Spyder IDE ( https://github.com/spyder-ide ) possède cette fonctionnalité, comme vous pouvez le voir sur mon écran d’affichage ci-dessous:

 enter image description here

Ceci est juste un fait objectif et non une publicité pour aucun IDE :) :) Je ne souhaite pas déclencher de débat sur cette question. 

6
Adrien A.

La solution la plus agréable que j'ai trouvée consiste à utiliser qgrid (voir ici , et également mentionné dans le document pandas ). Vous pouvez installer par

pip install qgrid

et vous devez ensuite effectuer une nouvelle installation (une seule fois) dans votre notebook IPython

qgrid.nbinstall()

Ensuite, c’est aussi simple que de prendre votre pandasdf et de courir

qgrid.show_grid(df)

L’autre bonne chose à faire est qu’il restitue également dans nbviewer. Voyez-le en action ici

5
cd98

Il y a tkintertable pour python2.7 et pandastable pour python3. 

3
ostrokach

Je travaille sur une interface graphique PyQt pour pandas DataFrame qui pourrait vous être utile. Cela inclut la copie, le filtrage et le tri.

https://Gist.github.com/jsexauer/f2bb0cc876828b54f2ed

2
jsexauer

La méthode to_clipboard () du cadre de données peut être utilisée pour copier rapidement, puis coller le cadre de données dans une feuille de calcul:

df.to_clipboard()
1
Mike Bannister

Il semble qu'il n'y ait pas de solution facile. Donc, voici une petite fonction pour ouvrir une image dans Excel. Ce n'est probablement pas un code de qualité de production, mais cela fonctionne pour moi!

def open_in_Excel(df, index=True, Excel_path="Excel.exe", tmp_path='.'):
    """Open dataframe df in Excel.

    Excel_path - path to your copy of Excel
    index=True - export the index of the dataframe as the first columns
    tmp_path    - directory to save the file in


    This creates a temporary file name, exports the dataframe to a csv of that file name,
    and then tells Excel to open the file (in read only mode). (It uses df.to_csv instead
    of to_Excel because if you don't have Excel, you still get the csv.)

    Note - this does NOT delete the file when you exit. 
    """

    f=tempfile.NamedTemporaryFile(delete=False, dir=tmp_path, suffix='.csv', prefix='tmp_')
    tmp_name=f.name
    f.close()

    df.to_csv(tmp_name, index=index)
    cmd=[Excel_path, '/r', '/e', tmp_name]
    try:
        ret_val=subprocess.Popen(cmd).pid
    except:
        print "open_in_Excel(): failed to open Excel"
        print "filename = ", tmp_name
        print "command line = ", cmd
        print "Unexpected error:", sys.exc_info()[0]

    return
1
Ross R

J'ai testé beaucoup de suggestions ici et aucune ne semble fonctionner ou s'installer facilement, en particulier pour Python 3, mais maintenant j'ai écrit une fonction qui accomplit ce que je voulais. Besoin de disposer de ces images en plein écran et de les faire défiler parfois.

Donc, dans un environnement Linux utilisant Libreoffice Calc, inspiré par cette réponse de Unix et Linux StackExchange, voici ce que vous pouvez faire dans Python 3:

import pandas as pd
import os

def viewDF(*dfs):
    filelist = ""
    for c, df in enumerate(dfs):    
        filename = 'tmp_df' + str(c) + '.csv'
        odsfile = 'tmp_df' + str(c) + '.ods'
        df.to_csv(filename)
        os.system("soffice --headless --convert-to ods  {}".format(filename))     
        filelist += odsfile + " "
    os.system("soffice --view {}".format(filelist)) 
    os.system("rm {}".format('tmp_df*'))

Utilisez-le comme ceci:

viewDF(df1, df2, df3)

J'ai appris quelque chose ici, à savoir la syntaxe de substitution Python 3, {}".format. Les fichiers ouverts sont en lecture seule. Dans tous les cas, il s'agit de fichiers qui sont ultérieurement supprimés. Il s'agit donc d'une interface graphique pour les images. Il créera plusieurs instances de Libreoffice Calc pour chaque cadre de données que vous lui donnerez, que vous pourrez afficher en plein écran sur des écrans distincts, puis une fois que vous aurez fermé Calc, il nettoiera lui-même. 

1
cardamom

Je vous recommande fortement d'utiliser QTableView et non QTableWidget. QTableView est basé sur la programmation par modèle.

Il existe 2 façons différentes par lesquelles ces widgets peuvent accéder à leurs données. La méthode traditionnelle implique des widgets qui incluent des conteneurs internes pour stocker des données. Cette approche est très intuitive, cependant, dans de nombreuses applications non triviales, elle entraîne des problèmes de synchronisation des données. La seconde approche est la programmation modèle/vue, dans laquelle les widgets ne gèrent pas les conteneurs de données internes.

J'ai écrit un modèle pour pandas dataframe

# -*- coding: utf-8 -*-
from PyQt5 import QtCore
from PyQt5 import QtWidgets
from PyQt5 import QtGui
import matplotlib.pyplot as plt

class PandasModel(QtCore.QAbstractTableModel):
    """
    Class to populate a table view with a pandas dataframe
    """

    def __init__(self, data, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self._data = data

    def rowCount(self, parent=None):
        return len(self._data.values)

    def columnCount(self, parent=None):
        return self._data.columns.size

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid():
            if role == QtCore.Qt.DisplayRole:
                if(index.column() != 0):
                    return str('%.2f'%self._data.values[index.row()][index.column()])
                else:
                    return str(self._data.values[index.row()][index.column()])
        return None

    def headerData(self, section, orientation, role):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return self._data.columns[section]
        Elif orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
            return str(self._data.index[section])
        return None

    def flags(self, index):
        flags = super(self.__class__,self).flags(index)
        flags |= QtCore.Qt.ItemIsSelectable
        flags |= QtCore.Qt.ItemIsEnabled
        return flags


if __name__=='__main__':
    import pandas as pd
    import numpy as np
    df = pd.DataFrame()
    df['Field1']=np.arange(0,10,.5)
    df['Field2']=np.arange(0,10,.5)
    app = QtWidgets.QApplication([])
    table = QtWidgets.QTableView()
    mymodel = PandasModel(df)
    table.setModel(mymodel)
    table.show()
    app.exec_()

Vous pouvez facilement modifier le modèle pour modifier ou afficher les éléments en fonction de vos besoins. Pour plus d'informations, consultez modelview

 enter image description here

1
Ali Mirzaei

J'utilise des ordinateurs portables ipython pour conduire des pandas - les ordinateurs portables constituent un moyen propre et agréable de construire et d'interagir progressivement avec les structures de données des pandas, y compris l'affichage HTML de cadres de données: http://ipython.org/notebook.html

1
stevegt

J'ai aussi cherché une interface graphique très simple. Je suis surpris que personne ne mentionne gtabview. Il est facile à installer (pip3 install gtabview), et il charge des données extrêmement rapidement . Je recommande d’utiliser gtabview si vous n’utilisez pas Spyder ou Pycharm. 

0
Matthew Son

Je ne suis pas moi-même un utilisateur de Pandas, mais une recherche rapide de "pandas gui" révèle la proposition du projet Pandas GSOC 2012 :

Actuellement, le seul moyen d'interagir avec ces objets est via l'API. Ce projet propose d’ajouter une interface graphique simple Qt ou Tk avec laquelle visualiser et manipuler ces objets.

Donc, il n'y a pas d'interface graphique, mais si vous en écrivez une en utilisant Qt ou Tk, le projet pourrait être intéressé par votre code.

0
Fred Foo

Vous pouvez utiliser GitHub Atom avec le plugin Hydrogen. Sous Mac, vous pouvez utiliser les touches Cmd + Maj pour exécuter ligne par ligne. Même vous ne pouvez sélectionner que la variable et voir à l'intérieur. Les DataFrames sont bien affichés et vous pouvez même les copier. J'ai écrit un blog pour montrer comment les configurer . http://ojitha.blogspot.com.au/2016/08/atom-as-spark-editor.html

0
Ojitha