아미(아름다운미소)

str.split to numpy.char.partition 본문

카테고리 없음

str.split to numpy.char.partition

유키공 2025. 3. 18. 22:01
import pandas as pd

# 예시 데이터프레임 생성
data = {'y_col': ['abc_def', 'ghi_jkl_mno', 'pqr', None, 'stu_vwx_xyz']}
result_df = pd.DataFrame(data)

# 정규 표현식을 사용하여 '_'로 분할
debris = result_df['y_col'].str.extract(r'([^_]+)_?([^_]*)')

# 결과를 새로운 열에 할당
result_df['a_pandas'] = debris[0]
result_df['b_pandas'] = debris[1]

print(result_df)
import pandas as pd
import numpy as np
import time

# 1. 400만 개의 테스트 데이터 생성 (None 및 _가 없는 경우 포함)
np.random.seed(42)  # 재현성을 위한 시드 설정
data = {
    'y_col': [
        f"text_{np.random.randint(1, 100)}" if np.random.rand() > 0.3 else (
            "no_separator" if np.random.rand() > 0.5 else None
        ) for _ in range(4000000)
    ]
}
result_df = pd.DataFrame(data)

# 2. pandas str.split 사용 및 시간 측정
start_time = time.time()
debris = result_df['y_col'].str.split('_', expand=True)
result_df['a_pandas'] = debris[0]
result_df['b_pandas'] = debris[1]  # NaN이 자동 할당됨
pandas_time = time.time() - start_time

# 3. numpy np.char.split 사용 및 시간 측정
start_time = time.time()

# None 값을 NaN으로 유지하고, NaN이 아닌 경우만 문자열로 변환
y_col_np = result_df['y_col'].values
mask = pd.isna(y_col_np)  # NaN 값의 마스크 생성

# NaN이 아닌 값만 문자열로 변환
y_col_np = np.where(mask, '', y_col_np.astype(str))

# np.char.split 적용
arr = np.char.split(y_col_np, '_')

# 첫 번째 부분 할당 (object 타입으로 변환)
a_numpy = np.where(mask, np.nan, np.array([x[0] if len(x) > 0 else np.nan for x in arr], dtype=object))

# 두 번째 부분 할당 (빈 문자열이면 NaN 처리)
b_numpy = np.where(mask, np.nan, np.array([x[1] if len(x) > 1 else np.nan for x in arr], dtype=object))

# 결과를 데이터프레임에 추가
result_df['a_numpy'] = a_numpy
result_df['b_numpy'] = b_numpy
numpy_time = time.time() - start_time

# 4. pandas vs numpy 결과 비교
assert result_df['a_pandas'].equals(result_df['a_numpy']), "Error: 'a' 열이 일치하지 않음!"
assert result_df['b_pandas'].equals(result_df['b_numpy']), "Error: 'b' 열이 일치하지 않음!"

# 5. 시간 및 결과 출력
print("✅ pandas와 numpy 결과가 동일합니다!\n")
print(f"pandas 처리 시간: {pandas_time:.4f} 초")
print(f"numpy 처리 시간: {numpy_time:.4f} 초")
print(f"numpy가 pandas보다 {pandas_time / numpy_time:.2f}배 빠릅니다.\n")

# 6. 최종 데이터 샘플 출력 (상위 10개만 확인)
print(result_df[['y_col', 'a_pandas', 'b_pandas', 'a_numpy', 'b_numpy']].head(10))
import pandas as pd
import numpy as np
import time

# 1. 400만 개의 테스트 데이터 생성 (None 및 _가 없는 경우 포함)
np.random.seed(42)  # 재현성을 위한 시드 설정
data = {
    'y_col': [
        f"text_{np.random.randint(1, 100)}" if np.random.rand() > 0.3 else (
            "no_separator" if np.random.rand() > 0.5 else None
        ) for _ in range(4000000)
    ]
}
result_df = pd.DataFrame(data)

# 2. pandas str.split 사용 및 시간 측정
start_time = time.time()
debris = result_df['y_col'].str.split('_', expand=True)
result_df['a_pandas'] = debris[0]
result_df['b_pandas'] = debris[1]  # NaN이 자동 할당됨
pandas_time = time.time() - start_time

# 3. numpy np.char.partition 사용 및 시간 측정
start_time = time.time()

# None 값을 NaN으로 유지하고, NaN이 아닌 경우만 문자열로 변환
y_col_np = result_df['y_col'].values
mask = pd.isna(y_col_np)  # NaN 값의 마스크 생성

# NaN이 아닌 값만 문자열로 변환
y_col_np = np.where(mask, '', y_col_np.astype(str))

# np.char.partition 적용
arr = np.char.partition(y_col_np, '_')

# 첫 번째 부분 할당 (object 타입으로 변환)
a_numpy = np.where(mask, np.nan, arr[:, 0].astype(object))  # NaN인 경우 NaN으로 유지

# 두 번째 부분 할당 (빈 문자열이면 NaN 처리)
b_numpy = np.where(mask, np.nan, np.where(arr[:, 1] == '', np.nan, arr[:, 2].astype(object)))

# 결과를 데이터프레임에 추가
result_df['a_numpy'] = a_numpy
result_df['b_numpy'] = b_numpy
numpy_time = time.time() - start_time

# 4. pandas vs numpy 결과 비교
assert result_df['a_pandas'].equals(result_df['a_numpy']), "Error: 'a' 열이 일치하지 않음!"
assert result_df['b_pandas'].equals(result_df['b_numpy']), "Error: 'b' 열이 일치하지 않음!"

# 5. 시간 및 결과 출력
print("✅ pandas와 numpy 결과가 동일합니다!\n")
print(f"pandas 처리 시간: {pandas_time:.4f} 초")
print(f"numpy 처리 시간: {numpy_time:.4f} 초")
print(f"numpy가 pandas보다 {pandas_time / numpy_time:.2f}배 빠릅니다.\n")

# 6. 최종 데이터 샘플 출력 (상위 10개만 확인)
print(result_df[['y_col', 'a_pandas', 'b_pandas', 'a_numpy', 'b_numpy']].head(10))
Comments