128 lines
5.0 KiB
Python
128 lines
5.0 KiB
Python
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 |