2

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?

Taras
35.7k5 gold badges77 silver badges151 bronze badges
asked Jun 2 at 12:10
3
  • Does my answer work? Commented 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. Commented Jun 10 at 17:35
  • 1
    Please provide more details, or simply share a sample of your data Commented Jun 17 at 7:14

3 Answers 3

6

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)
answered Jun 2 at 13:22
0
3

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.

answered Jun 2 at 13:55
3

Another suggestion is to utilise the .exportAttributes() method of the QgsJsonUtils class.

Let's assume there is a layer called 'extent_TEST':

input

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:

result

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:

answered Jun 2 at 17:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.