Caso de combate real de Pandas | clasificación de nivel de onda fría de actividad de aire frío

Prefacio

El texto y las imágenes de este artículo son de Internet y son únicamente con fines de aprendizaje y comunicación. No tienen ningún uso comercial. Si tiene alguna pregunta, comuníquese con nosotros para su procesamiento.

PD: Si necesita materiales de aprendizaje de Python, puede hacer clic en el enlace de abajo para obtenerlo usted mismo.

Materiales de aprendizaje gratuitos de Python y respuestas de comunicación grupal Haga clic para unirse


Hola a todos, hoy les presentaré cómo usar las funciones básicas groupby y los métodos diff para resolver las abrumadoras necesidades a través de una lógica compleja y clara, elegante
directorio ~ :

  • análisis de demanda
  • Leer datos
  • Toma un grupo para probar
  • Obtenga la identificación de datos correspondiente que cumpla con las condiciones de definición de onda fría
  • Generador de números de grupo
  • La prueba calcula la ola de frío para todas las estaciones.
  • Prueba todos los niveles de ola de frío
  • Código completo

análisis de demanda

Definición de ola de frío:

 

Formato de entrada y salida de datos:

 

Confirmación de estadísticas:

 

No entendí al principio, cómo calcular la caída de temperatura superior a 8 grados en 24 horas, después de confirmar con el lado de la demanda, se puede calcular por la diferencia de temperatura de 2 días. De manera similar, el rango de enfriamiento dentro de las 48 horas puede representarse por la diferencia de temperatura de 3 días, y el rango de enfriamiento dentro de las 72 horas puede representarse por la diferencia de temperatura de 4 días. La explicación del lado de la demanda:

 

Bueno, una vez que comprendamos los requisitos, podemos comenzar a trabajar:

Leer datos

Primero lea los datos:

import pandas as pd
import numpy as np

df = pd.read_csv("data.csv")
df

resultado:

 

Toma un grupo para probar

Saque un grupo para probar:

tmp = df.groupby('number').get_group('e332')
tmp

resultado:

 

Obtenga la identificación de datos correspondiente que cumpla con las condiciones de definición de onda fría

 

La situación extrema en la figura anterior muestra que los tres identificadores que cumplen con las condiciones pueden estar duplicados, por lo que usé set, un conjunto desordenado y no repetido para guardar los identificadores:

cold_wave_idxs = set()
# 获取2天内降温幅度超过8对应的数据id
ids = tmp.index[tmp.temperature.diff(-1) >= 8].values
cold_wave_idxs.update(ids)
cold_wave_idxs.update(ids+1)
# 获取3天内降温幅度超过10对应的数据id
ids = tmp.index[tmp.temperature.diff(-2) >= 10].values
cold_wave_idxs.update(ids)
cold_wave_idxs.update(ids+1)
cold_wave_idxs.update(ids+2)
# 获取4天内降温幅度超过12对应的数据id
ids = tmp.index[tmp.temperature.diff(-3) >= 12].values
cold_wave_idxs.update(ids)
cold_wave_idxs.update(ids+1)
cold_wave_idxs.update(ids+2)
cold_wave_idxs.update(ids+3)
# 排序并转换成列表
cold_wave_idxs = sorted(cold_wave_idxs)
print(cold_wave_idxs)

resultado:

[11928, 11929, 11930, 11931, 11939, 11940, 11949, 11950, 11951, 11952, 11955, 11956, 11957, 11958, 12007, 12008, 12154, 12155, 12192, 12193, 12201, 12202, 12203, 12223, 12224 , 12225, 12228, 12229, 12230] En el
código anterior, cold_wave_idxs.update (ids + 1) significa que el último id de cada id en la lista de ids también se agrega a la lista final, utilizando las características de numerosas variables de difusión de matriz , + Lo mismo ocurre con 2 y +3.

El resultado anterior es que la identificación de datos correspondiente que cumple con la definición de onda fría se calcula a partir del grupo con el código de estación de 'e332'.

Se puede ver en los resultados que cualquier identificación continua se puede considerar como un proceso de onda fría, por lo que ahora necesitamos agrupar cada proceso de onda fría en un grupo. Para hacer tal agrupación, inventé un generador de números de grupo Escrito, lo siguiente se ha encapsulado en un método:

Generador de números de grupo

def generate_group_num(values, diff=1):
    group_ids = []
    group_id = 0
    last_v = 0
    for value in values:
        if value-last_v > diff:
            group_id += 1
        group_ids.append(group_id)
        last_v = value
    return group_ids

El método anterior implementa un generador de números de agrupación, y todos los números consecutivos en una secuencia recibirán el mismo número de agrupación.

Pruebe el efecto de agrupación:

for i, cold_wave_idx_serial in pd.Series(cold_wave_idxs).groupby(generate_group_num(cold_wave_idxs)):
    cold_wave_idx_serial = cold_wave_idx_serial.values
    print(cold_wave_idx_serial)

resultado:

[11928 11929 11930 11931]
[11939 11940]
[11949 11950 11951 11952]
[11955 11956 11957 11958]
[12007 12008]
[12154 12155]
[12192 12193]
[12201 12202 12203]
[12223 12224 12225]
[12228 12229 12230]

A partir de los resultados, podemos ver que todas las secuencias continuas se agrupan en un grupo y las secuencias no continuas no se agrupan en un solo grupo.

La prueba calcula la ola de frío para todas las estaciones.

Primero, encapsule el proceso de obtención de la identificación que satisfaga la definición de onda fría en un método:

def get_cold_wave_idxs(df, cold_wave_level=(8, 10, 12)):
    cold_wave_idxs = set()
    ids = df.index[df.temperature.diff(-1) >= cold_wave_level[0]].values
    cold_wave_idxs.update(ids)
    cold_wave_idxs.update(ids+1)
    ids = df.index[df.temperature.diff(-2) >= cold_wave_level[1]].values
    cold_wave_idxs.update(ids)
    cold_wave_idxs.update(ids+1)
    cold_wave_idxs.update(ids+2)
    ids = df.index[df.temperature.diff(-3) >= cold_wave_level[2]].values
    cold_wave_idxs.update(ids)
    cold_wave_idxs.update(ids+1)
    cold_wave_idxs.update(ids+2)
    cold_wave_idxs.update(ids+3)
    return sorted(cold_wave_idxs)

Entonces corre:

cold_wave_result = []

for number, tmp in df.groupby('number'):
    cold_wave_idxs = get_cold_wave_idxs(tmp, (8, 10, 12))
    for i, cold_wave_idx_serial in pd.Series(cold_wave_idxs).groupby(generate_group_num(cold_wave_idxs)):
        cold_wave_idx_serial = cold_wave_idx_serial.values
        start_id, end_id = cold_wave_idx_serial[0], cold_wave_idx_serial[-1]
        #  假如最低温度小于4度,则说明满足全部条件
        if tmp.loc[end_id, 'temperature'] <= 4:
            cold_wave_result.append(
                (number, tmp.loc[start_id, 'date'], tmp.loc[end_id, 'date'],
                 tmp.loc[start_id, 'temperature'], tmp.loc[end_id, 'temperature'],
                 end_id-start_id+1,
                 tmp.loc[start_id, 'temperature'] -tmp.loc[end_id, 'temperature'],
                 '寒潮'
                 )
            )
cold_wave_result = pd.DataFrame(cold_wave_result, columns=[
    '站号', '开始日期', '结束日期', '开始温度', '结束温度',  '寒潮天数', '温度差', '寒潮类型'])
cold_wave_result

resultado:


Se siente bien.

 

Pruebe todos los niveles de ola de frío:

Prueba todos los niveles de ola de frío

cold_wave_all = [
    {
        'cold_wave_temperature_diffs': (8, 10, 12),
        'min_temperature_limit': 4,
        'cold_wave_type': '寒潮'
    },
    {
        'cold_wave_temperature_diffs': (10, 12, 14),
        'min_temperature_limit': 2,
        'cold_wave_type': '强寒潮'
    },
    {
        'cold_wave_temperature_diffs': (12, 14, 16),
        'min_temperature_limit': 0,
        'cold_wave_type': '超强寒潮'
    }
]
cold_wave_result = []

for number, tmp in df.groupby('number'):
    for cold_wave_dict in cold_wave_all:
        cold_wave_idxs = get_cold_wave_idxs(tmp, cold_wave_dict['cold_wave_temperature_diffs'])
        if len(cold_wave_idxs) < 2:
            continue
        for i, cold_wave_idx_serial in pd.Series(cold_wave_idxs).groupby(generate_group_num(cold_wave_idxs)):
            cold_wave_idx_serial = cold_wave_idx_serial.values
            start_id, end_id = cold_wave_idx_serial[0], cold_wave_idx_serial[-1]
            #  假如最低温度小于指定度数,则说明满足全部条件
            if tmp.loc[end_id, 'temperature'] <= cold_wave_dict['min_temperature_limit']:
                cold_wave_result.append(
                    (number, tmp.loc[start_id, 'date'], tmp.loc[end_id, 'date'],
                     tmp.loc[start_id, 'temperature'], tmp.loc[end_id, 'temperature'],
                     end_id-start_id+1,
                     tmp.loc[start_id, 'temperature'] - tmp.loc[end_id, 'temperature'],
                     cold_wave_dict['cold_wave_type']
                     )
                )
cold_wave_result = pd.DataFrame(cold_wave_result, columns=[
    '站号', '开始日期', '结束日期', '开始温度', '结束温度',  '寒潮天数', '温度差', '寒潮类型'])
cold_wave_result

resultado:


No se han encontrado errores por el momento. Así que resuelve el código final:

 

Código completo

import pandas as pd
import numpy as np


def generate_group_num(values, diff=1):
    group_ids = []
    group_id = 0
    last_v = 0
    for value in values:
        if value-last_v > diff:
            group_id += 1
        group_ids.append(group_id)
        last_v = value
    return group_ids


def get_cold_wave_idxs(df, cold_wave_level=(8, 10, 12)):
    cold_wave_idxs = set()
    ids = df.index[df.temperature.diff(-1) >= cold_wave_level[0]].values
    cold_wave_idxs.update(ids)
    cold_wave_idxs.update(ids+1)
    ids = df.index[df.temperature.diff(-2) >= cold_wave_level[1]].values
    cold_wave_idxs.update(ids)
    cold_wave_idxs.update(ids+1)
    cold_wave_idxs.update(ids+2)
    ids = df.index[df.temperature.diff(-3) >= cold_wave_level[2]].values
    cold_wave_idxs.update(ids)
    cold_wave_idxs.update(ids+1)
    cold_wave_idxs.update(ids+2)
    cold_wave_idxs.update(ids+3)
    return sorted(cold_wave_idxs)


df = pd.read_csv("data.csv")
cold_wave_all = [
    {
        'cold_wave_temperature_diffs': (8, 10, 12),
        'min_temperature_limit': 4,
        'cold_wave_type': '寒潮'
    },
    {
        'cold_wave_temperature_diffs': (10, 12, 14),
        'min_temperature_limit': 2,
        'cold_wave_type': '强寒潮'
    },
    {
        'cold_wave_temperature_diffs': (12, 14, 16),
        'min_temperature_limit': 0,
        'cold_wave_type': '超强寒潮'
    }
]
cold_wave_result = []

for number, tmp in df.groupby('number'):
    for cold_wave_dict in cold_wave_all:
        cold_wave_idxs = get_cold_wave_idxs(tmp, cold_wave_dict['cold_wave_temperature_diffs'])
        if len(cold_wave_idxs) < 2:
            continue
        for i, cold_wave_idx_serial in pd.Series(cold_wave_idxs).groupby(generate_group_num(cold_wave_idxs)):
            cold_wave_idx_serial = cold_wave_idx_serial.values
            start_id, end_id = cold_wave_idx_serial[0], cold_wave_idx_serial[-1]
            #  假如最低温度小于指定度数,则说明满足全部条件
            if tmp.loc[end_id, 'temperature'] <= cold_wave_dict['min_temperature_limit']:
                cold_wave_result.append(
                    (number, tmp.loc[start_id, 'date'], tmp.loc[end_id, 'date'],
                     tmp.loc[start_id, 'temperature'], tmp.loc[end_id, 'temperature'],
                     end_id-start_id+1,
                     tmp.loc[start_id, 'temperature'] - tmp.loc[end_id, 'temperature'],
                     cold_wave_dict['cold_wave_type']
                     )
                )
cold_wave_result = pd.DataFrame(cold_wave_result, columns=[
    '站号', '开始日期', '结束日期', '开始温度', '结束温度',  '寒潮天数', '温度差', '寒潮类型'])
cold_wave_result.to_excel("cold_wave.xlsx", index=False)

El resultado final:

Supongo que te gusta

Origin blog.csdn.net/pythonxuexi123/article/details/112793751
Recomendado
Clasificación