import pandas as pd import numpy as np from datetime import datetime, timedelta def guaCalc_huangjijingshi(Map64Gua, Map24Jieqi, kDate): """ Calculate year, month, day, and hour gua based on Huangji Jingshi method Args: Map64Gua (pd.DataFrame): 64 gua mapping table Map24Jieqi (pd.DataFrame): 24 solar terms data kDate (datetime): Target date for calculation Returns: tuple: (Gua4Hour, Gua1Day, Gua1Month, Gua1Year, GuaLuck) """ # Helper functions that need to be implemented separately from bianyao_huangjijingshi import bianyao_huangjijingshi from tuigua_huangjijingshi import tuigua_huangjijingshi # Bagua for 360 years yearRef = {'trigram': '姤', 'value_2binary': '111110', 'start_year': 1744, 'end_year': 2103} Gua360Year = bianyao_huangjijingshi(Map64Gua, yearRef['value_2binary']) Gua360Year['yearStart'] = [yearRef['start_year'] + i * 60 for i in range(7)] Gua360Year['yearStart'] = pd.concat([pd.Series([yearRef['start_year']]), Gua360Year['yearStart']]).reset_index(drop=True) Gua360Year['yearEnd'] = [start + 59 for start in Gua360Year['yearStart']] Gua360Year.loc[0, 'yearEnd'] = yearRef['end_year'] # Bagua for 60 years kYear = kDate.year kYearOrig = kYear solar_terms = Map24Jieqi solar_terms1 = solar_terms[solar_terms['Solar_Terms'] == '冬至'] # Find the last winter solstice before our date k1 = np.where((kDate - solar_terms1['As_Of_Date']) > pd.Timedelta(0))[0][-1] kYear = (solar_terms1['As_Of_Date'].iloc[k1] + pd.Timedelta(days=90)).year # Find which 60-year period we're in mask = ((Gua360Year['yearStart'] <= kYear) & (Gua360Year['yearEnd'] >= kYear)) k1 = np.where(mask)[0] if len(k1) > 1: k1 = k1[1:] k1 = k1[0] a1 = Gua360Year['value_2binary'].iloc[k1] a2 = kYear - Gua360Year['yearStart'].iloc[k1] Gua1Year = tuigua_huangjijingshi(Map64Gua, a1, a2 + 1) Gua1Year['Type'] = 'year' # Get the yaoAll value correctly if isinstance(Gua1Year, pd.DataFrame): trigram_value = Gua1Year['trigram'].iloc[0] yaoAll_value = Gua1Year['yaoAll'].iloc[0] else: trigram_value = Gua1Year['trigram'] yaoAll_value = Gua1Year['yaoAll'] # Bagua for 360 days (months) dayRef = { 'trigram': trigram_value, 'yaoAll': yaoAll_value, 'start_day': 1, 'end_day': 360 } Gua365days = bianyao_huangjijingshi(Map64Gua, str(yaoAll_value)) # Find important solar terms solar_termsSimple = Map24Jieqi[Map24Jieqi['isImportant'] == 1] # Find the last important solar term before our date kk = np.where((kDate - solar_termsSimple['As_Of_Date']) > pd.Timedelta(0))[0][-1] # Find winter solstice within these terms kk2 = np.where(solar_termsSimple['Solar_Terms'].iloc[:kk+1] == '冬至')[0][-1] a1 = Gua365days['value_2binary'].iloc[kk - kk2 + 1] Gua1Month = Gua365days.iloc[[kk - kk2 + 1]].copy() Gua1Month['Type'] = 'month' # Calculate day gua kDateMonth = solar_termsSimple['As_Of_Date'].iloc[kk] kGap = (kDate.date() - kDateMonth.date()).days a2 = round(kGap) Gua1Day = tuigua_huangjijingshi(Map64Gua, a1, a2) Gua1Day['Type'] = 'day' # Calculate hour gua (4-hour blocks) # Get yaoAll value from Gua1Day - handle both DataFrame and scalar cases if isinstance(Gua1Day, pd.DataFrame): day_yaoAll = Gua1Day['yaoAll'].iloc[0] else: day_yaoAll = Gua1Day['yaoAll'] Gua24Hours = bianyao_huangjijingshi(Map64Gua, str(day_yaoAll)) k1 = min(int(np.floor(kDate.hour / 4))+1, len(Gua24Hours) - 1) #ceil修改为了floor Gua4Hour = Gua24Hours.iloc[[k1]].copy() Gua4Hour['Type'] = 'hour' def to_single_row_df(x): if isinstance(x, pd.Series): return pd.DataFrame([x])[['yao1', 'yao2', 'yao3', 'yao4', 'yao5', 'yao6']] elif isinstance(x, pd.DataFrame): return x[['yao1', 'yao2', 'yao3', 'yao4', 'yao5', 'yao6']].reset_index(drop=True) else: raise TypeError("Unsupported type: must be Series or DataFrame") # Calculate luck gua # abc = pd.concat([ # Gua1Year[['yao1', 'yao2', 'yao3', 'yao4', 'yao5', 'yao6']], # Gua1Month[['yao1', 'yao2', 'yao3', 'yao4', 'yao5', 'yao6']], # Gua1Day[['yao1', 'yao2', 'yao3', 'yao4', 'yao5', 'yao6']], # Gua4Hour[['yao1', 'yao2', 'yao3', 'yao4', 'yao5', 'yao6']] # ]) abc = pd.concat([ to_single_row_df(Gua1Year), to_single_row_df(Gua1Month), to_single_row_df(Gua1Day), to_single_row_df(Gua4Hour) ], ignore_index=True) abc2 = np.mod(np.nansum(abc, axis=0), 2)[:6] abc3 = np.sum(abc2 * [1, 2, 4, 8, 16, 32]) k1 = np.where(Map64Gua['value_2binary'] == abc3)[0][0] GuaLuck = Map64Gua.iloc[[k1]].copy() GuaLuck['Type'] = 'luck' # print(abc.dtypes) # print(abc) return Gua4Hour, Gua1Day, Gua1Month, Gua1Year, GuaLuck