-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-26887][SQL][PYTHON] Create datetime.date directly instead of creating datetime64[ns] as intermediate data. #23795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1681,38 +1681,53 @@ def from_arrow_schema(arrow_schema): | |
| for field in arrow_schema]) | ||
|
|
||
|
|
||
| def _check_series_convert_date(series, data_type): | ||
| """ | ||
| Cast the series to datetime.date if it's a date type, otherwise returns the original series. | ||
| def _arrow_column_to_pandas(column, data_type): | ||
| """ Convert Arrow Column to pandas Series. | ||
|
|
||
| If the given column is a date type column, creates a series of datetime.date directly instead | ||
| of creating datetime64[ns] as intermediate data. | ||
|
|
||
| :param series: pandas.Series | ||
| :param data_type: a Spark data type for the series | ||
| :param series: pyarrow.lib.Column | ||
| :param data_type: a Spark data type for the column | ||
| """ | ||
| import pyarrow | ||
| import pandas as pd | ||
| import pyarrow as pa | ||
| from distutils.version import LooseVersion | ||
| # As of Arrow 0.12.0, date_as_objects is True by default, see ARROW-3910 | ||
| if LooseVersion(pyarrow.__version__) < LooseVersion("0.12.0") and type(data_type) == DateType: | ||
| return series.dt.date | ||
| # Since Arrow 0.11.0, support date_as_object to return datetime.date instead of np.datetime64. | ||
|
||
| if LooseVersion(pa.__version__) < LooseVersion("0.11.0"): | ||
| if type(data_type) == DateType: | ||
| return pd.Series(column.to_pylist(), name=column.name) | ||
| else: | ||
| return column.to_pandas() | ||
| else: | ||
| return series | ||
| return column.to_pandas(date_as_object=True) | ||
|
|
||
|
|
||
| def _arrow_table_to_pandas(table, schema): | ||
| """ Convert Arrow Table to pandas DataFrame. | ||
|
|
||
| def _check_dataframe_convert_date(pdf, schema): | ||
| """ Correct date type value to use datetime.date. | ||
| If the given table contains a date type column, use `_arrow_column_to_pandas` for pyarrow<0.11 | ||
| or use `date_as_object` option for pyarrow>=0.11 to avoid creating datetime64[ns] as | ||
| intermediate data. | ||
|
|
||
| Pandas DataFrame created from PyArrow uses datetime64[ns] for date type values, but we should | ||
| use datetime.date to match the behavior with when Arrow optimization is disabled. | ||
|
|
||
| :param pdf: pandas.DataFrame | ||
| :param schema: a Spark schema of the pandas.DataFrame | ||
| :param table: pyarrow.lib.Table | ||
| :param schema: a Spark schema of the pyarrow.lib.Table | ||
| """ | ||
| import pyarrow | ||
| import pandas as pd | ||
| import pyarrow as pa | ||
| from distutils.version import LooseVersion | ||
| # As of Arrow 0.12.0, date_as_objects is True by default, see ARROW-3910 | ||
| if LooseVersion(pyarrow.__version__) < LooseVersion("0.12.0"): | ||
| for field in schema: | ||
| pdf[field.name] = _check_series_convert_date(pdf[field.name], field.dataType) | ||
| return pdf | ||
| # Since Arrow 0.11.0, support date_as_object to return datetime.date instead of np.datetime64. | ||
| if LooseVersion(pa.__version__) < LooseVersion("0.11.0"): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks good @ueshin. @ueshin, @BryanCutler , BTW, which version of PyArrow do you think we should bump up to in Spark 3.0.0? I was thinking about matching it to 0.12.0, or 0.11.0. I think it's overhead that we should test all the pyarrow versions.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to bump to 0.12.0 because I think that would allow us to clean up the code the most, but since it's a raised error if the user doesn't have that version, it might too restrictive. Let's definitely make a JIRA to discuss more. |
||
| if any(type(field.dataType) == DateType for field in schema): | ||
| return pd.concat([_arrow_column_to_pandas(column, field.dataType) | ||
| for column, field in zip(table.itercolumns(), schema)], axis=1) | ||
| else: | ||
| return table.to_pandas() | ||
| else: | ||
| return table.to_pandas(date_as_object=True) | ||
|
|
||
|
|
||
| def _get_local_timezone(): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: I think these details belong as a comment internally rather than in the doc string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to say that for dates this will return
datetime.date, but yeah maybe move the part about datetime[64] as intermediate to an internal comment._arrow_table_to_pandashas a comment that the reason for this is to match pyspark w/o arrow, but maybe it would be good to add here as well.