Перевести SQL в поляры и панды

Может кто-нибудь помочь мне перевести

SELECT (TRUNC(lat/0.5)*0.5) AS ll_lat, (TRUNC(lon/0.5)*0.5) AS ll_lon, COUNT(lat) AS  strikes FROM lightning GROUP BY ll_lat, ll_lon;

в код Pandas и Polars, когда я пытался

# Pandas
df['ll_lat'] = (df['lat'] // 0.1 * 0.1).round(1)
df['ll_lon'] = (df['lon'] // 0.1 * 0.1).round(1)
df['temporalBasket'] = df['eventtime'].astype(str).str[:13]
df = df.groupby(['ll_lat', 'll_lon', 'temporalBasket']).agg(strikes=('lat', 'count'))
# 3763740 rows × 1 columns
# Polars
df_p_out = df_p.groupby(
    (pl.col("lat") // 0.1 * 0.1).alias("ll_lat"),
    (pl.col("lon") // 0.1 * 0.1).alias("ll_lon"),
    pl.col("eventtime").dt.truncate("1h").alias("temporalBasket"),
).agg(strikes=pl.col("lat").count())
# shape: (3763740, 4)

в отличие от формы SQL (10168 строк × 3 столбца). Мой Dataframe выглядит так

Пожалуйста, предоставьте минимальный воспроизводимый пример, в настоящее время сложно что-либо протестировать. Также убедитесь, что округление работает должным образом (вы используете 0.5 в SQL и 0.1 в python).

mozway 11.04.2023 15:15

Не группируйте по temporalBasket. Попробуйте: df = df.groupby(['ll_lat', 'll_lon']).agg(strikes=('lat', 'count'), event=('temporalBasket', 'first'))

Corralien 11.04.2023 15:21

В вашем sql нет элемента времени, тогда как в ваших полярах он есть. Либо поместите темпоральную корзину в sql, либо уберите ее из своей группы полярников.

Dean MacGregor 11.04.2023 15:30

Кроме того, координаты wgs84 не имеют фиксированных расстояний, поэтому группировка путем округления координат будет иметь большие площади по мере приближения к экватору. wiki.gis.com/wiki/index.php/Геодезическая_система

Dean MacGregor 11.04.2023 15:56

@DeanMacGregor очень хороший вопрос, сэр, как мне перевести временную корзину в SQL?

Curious 11.04.2023 16:27
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать:

df['ll_lat'] = (df['lat'] // 0.5 * 0.5).round(1)  # 0.5 or 0.1?
df['ll_lon'] = (df['lon'] // 0.5 * 0.5).round(1)  # 0.5 or 0.1?
df['temporalBasket'] = df['eventtime'].str[:13]   # YYYY-MM-DD HH

out = (df.groupby(['ll_lat', 'll_lon'], as_index=False)
         .agg(strikes=('lat', 'count'),
              event=('temporalBasket', 'first')))

В то время как в df 1000 записей, out имеет 857 строк после агрегирования:

>>> out
     ll_lat  ll_lon  strikes          event
0     -46.0   -72.5        1  2022-09-12 23
1     -38.5   -58.0        1  2022-06-27 07
2     -38.0   -58.0        1  2022-04-20 03
3     -37.0   -72.5        1  2023-03-29 01
4     -35.0   -59.0        1  2023-01-23 12
..      ...     ...      ...            ...
852    63.5    11.0        1  2022-09-08 08
853    63.5    20.0        1  2022-04-24 03
854    64.5    21.0        1  2022-05-02 11
855    65.0   -14.0        1  2022-10-12 14
856    65.5    78.0        1  2023-03-07 11

[857 rows x 4 columns]

>>> df
           lat         lon            eventtime  ll_lat  ll_lon temporalBasket
0    45.804626   15.874926  2023-03-30 09:48:05    45.5    15.5  2023-03-30 09
1    34.674118  -92.351753  2022-06-13 22:18:29    34.5   -92.5  2022-06-13 22
2    50.614098    3.124432  2023-02-07 22:29:37    50.5     3.0  2023-02-07 22
3   -27.143572  -56.766484  2022-05-14 11:08:50   -27.5   -57.0  2022-05-14 11
4    43.503934   16.523779  2022-10-18 01:31:38    43.5    16.5  2022-10-18 01
..         ...         ...                  ...     ...     ...            ...
995  53.909600   37.736000  2022-12-15 13:45:56    53.5    37.5  2022-12-15 13
996  55.870995   -4.249439  2023-01-06 03:44:50    55.5    -4.5  2023-01-06 03
997   5.196440  -74.234923  2022-08-10 01:51:16     5.0   -74.5  2022-08-10 01
998  -6.509253  106.897496  2022-12-17 17:24:56    -7.0   106.5  2022-12-17 17
999  49.788203   19.705980  2022-08-24 15:03:58    49.5    19.5  2022-08-24 15

[1000 rows x 6 columns]

Как ни странно (даже после запуска с исправленной опечаткой (это 0,5) я не понимаю, что мне дает SQL. Я не уверен, почему аналогичный запрос дал бы мне 620886 строк вместо ожидаемых 10168, если только мой код не хорошо переведено Как мне воссоздать временную корзину в SQL, чтобы они совпадали?

Curious 11.04.2023 16:23

Не группируйте по временной корзине, чтобы проверить, есть ли у вас одинаковый результат.

Corralien 11.04.2023 16:26

Я получил тот же результат, сэр. Есть идеи, как перевести temporalBasket в SQL?

Curious 11.04.2023 16:30

eventime хранится как VARCHAR или DATETIME?

Corralien 11.04.2023 16:40

В БД PostgreSQL это text, а в файле паркета это datetime[ns] Сэр/Мадам.

Curious 11.04.2023 16:50

Может быть, вы можете использовать SUBSTRING для извлечения первых 13 символов?

Corralien 11.04.2023 16:53

@ Любопытно что-то вроде этого stackoverflow.com/questions/17492167/…

Dean MacGregor 11.04.2023 20:20

Да, но кажется, что ваш столбец текстовый, поэтому я не думаю, что вы можете использовать date_trunc, но идея с substring такая же.

Corralien 12.04.2023 00:02

Другие вопросы по теме