I have a layer with a Date-Time format entry that is populated from a calendar pop-up as defined in the Attributes Form.
If I 'Export - Save feature as...csv', my data is in the style dd/MM/yyyy HH:mm
. That's what I wanted.
But I want to pull the data from the layer and put it into a Pandas.DataFrame
to manipulate further before exporting it.
I am doing this with:
# Get layer from Combobox
lyr = self.dlg.mMapLayerComboBox.currentLayer()
cols = [f.name() for f in lyr.fields()]
# A generator to yield one row at a time
datagen = ([f[col] for col in cols] for f in lyr.getFeatures())
df = pd.DataFrame.from_records(data=datagen, columns=cols)
What I see if I save this df as a CSV file (viewed in Excel) is
PyQt5.QtCore.QDateTime(2025, 6, 2, 1, 0)
Or if viewed in Notepad:
"PyQt5.QtCore.QDateTime(2025, 6, 2, 1, 0)"
How do I get rid of the PyQt5....etc, or convert it to just date and time data?
Part of the rest of my code splits the Date-time into separate Date and Time columns. Do I correct this inside QGIS as it extracts from the layer to the df, or is there a PyQGIS way to convert a Dataframe column from what I have to what I want?
-
Does my answer work?Bera– Bera2025年06月10日 05:04:14 +00:00Commented Jun 10 at 5:04
-
Not at the moment. I have tried your answer, and the ones below and none seem to work for me. I suspect I am doing something wrong with my data entry, rather than 3 similar answers being incorrect. I will carry on experimenting.WillH– WillH2025年06月10日 17:35:53 +00:00Commented Jun 10 at 17:35
-
1Please provide more details, or simply share a sample of your dataTaras– Taras ♦2025年06月17日 07:14:59 +00:00Commented Jun 17 at 7:14
3 Answers 3
List all attributes, convert the pydatetimes to datetimes using .toPyDateTime
:
layer = iface.activeLayer()
cols = layer.fields().names() #List column names
attrs = [] #A list to hold all attributes
for f in layer.getFeatures(): #For each feature
a_list = f.attributes() #List its attributes
#Convert any qdatetimes to python datetimes, else keep original attribute
a_list = [x.toPyDateTime() if isinstance(x, QDateTime) else x for x in a_list]
attrs.append(a_list) #Append the converted attributes to the list
df = pd.DataFrame.from_records(data=attrs, column=cols)
An alternative would be to (save a temporary file and) read the file with geopandas:
import geopandas as gpd
layer = iface.activeLayer()
temp = processing.run("native:savefeatures", {'INPUT':layer,'OUTPUT':'TEMPORARY_OUTPUT','LAYER_NAME':'','DATASOURCE_OPTIONS':'','LAYER_OPTIONS':'','ACTION_ON_EXISTING_FILE':0})['OUTPUT']
df = gpd.read_file(temp)
print(df)
All pandas methods should work. You can delete the geometry column to get a classic pandas object.
Another suggestion is to utilise the .exportAttributes()
method of the QgsJsonUtils
class.
Let's assume there is a layer called 'extent_TEST':
To get a DataFrame
out of it, the following code could be applied:
import ast
import pandas as pd
from qgis.core import QgsProject, QgsJsonUtils
layer = QgsProject.instance().mapLayersByName('extent_TEST')[0]
data = [ast.literal_eval(QgsJsonUtils.exportAttributes(feat, layer)) for feat in layer.getFeatures()]
df = pd.DataFrame.from_dict(data)
It will lead to the following DataFrame
:
However, when creating a DataFrame
, the field types have to be additionally defined, otherwise, each Date or DateTime column will be treated as an object
-type.
References:
Explore related questions
See similar questions with these tags.