IF문 좀 대신 써줘

시간초과 코드

from sys import stdin

N, M = map(int, stdin.readline().strip().split())

powers = []
titles = []

for _ in range(N):
    title, power = map(str, stdin.readline().strip().split())
    power = int(power)
    powers.append(power)
    titles.append(title)

for _ in range(M):
    userPower = int(stdin.readline().strip())
    for idx in range(len(powers)):
        if userPower <= powers[idx]:
            print(titles[idx])
            break

 

성공 코드

from sys import stdin

N, M = map(int, stdin.readline().strip().split())

powers = []

for _ in range(N):
    title, power = map(str, stdin.readline().strip().split())
    powers.append([title, int(power)])


powers.sort(key=lambda x: x[1]) # 오름차순 정렬

for _ in range(M):
    power = int(stdin.readline().strip())
    start = 0
    end = len(powers)-1

    while start <= end:
        mid = (start+end) // 2
        if power > powers[mid][1]:
            start = mid + 1
        else:
            end = mid - 1

    print(powers[start][0])
728x90

타노스

 

내코드

from sys import stdin

# 사전순 가장 빠른 것을 출력해야 하기 때문에
# 1은 왼쪽에서 부터 삭제, 0은 오른쪽에서부터 삭제
s = stdin.readline().strip()

count0 = s.count("0")//2
count1 = s.count("1")//2

while count0 > 0 or count1 > 0:
    if count1 > 0:
        idx1 = s.index("1")
        s = list(s)
        s[idx1] = ''
        s = "".join(s)
        count1 -= 1
    if count0 > 0:
        idx0 = s.rindex("0")
        s = list(s)
        s[idx0] = ''
        s = "".join(s)
        count0 -= 1

print("".join(s))
728x90

시계열 데이터

시계열 데이터는 행과 행사이에 시간의 흐름(순서)가 있고, 행과 행 사이의 시간간격이 동일한 데이터를 의미한다.

예) 가게의 일별 매출량 데이터

 

날짜 요소 뽑기

날짜 타입의 변수로 부터 날짜의 요소(일, 월, 주차, ..)를 뽑을 수 있다.

  • .dt.날짜 요소
메서드 내용
df['date'].dt.date YYYY-MM-DD(문자)
df['date'].dt.year 연(4자리 숫자)
df['date'].dt.month 월(숫자)
df['date'].dt.month_name() 월(문자)
df['date'].dt.day 일(숫자)
df['date'].dt.time HH:MM:SS(문자)
df['date'].dt.hour 시(숫자)
df['date'].dt.minute 분(숫자)
df['date'].dt.second 초(숫자
df['date'].dt.quarter 분기(숫자)
df['date'].dt.day_name() 요일 이름(문자)
df['date'].dt.weekday 요일숫자(0-월, 1-화, 2-수, ...) (=dayofweek) 
df['date'].dt.dayofyear 연 기준 몇일째(숫자)
df['date'].dt.days_in_month 월 일수(숫자) (daysinmonth)

 

data = pd.DataFrame([
    ['2024-02-22', 20153],
    ['2024-02-23', 20546],
    ['2024-02-24', 2053],
    ['2024-02-25', 2033],
    ['2024-02-26', 2234532],
    ['2024-02-27', 2653261],
], columns=["Date", "Sales"])

data['Date'] = pd.to_datetime(data['Date'])

print(data['Date'].dt.date) # 각 행 별 날짜 출력 
print(data['Date'].dt.year) # 각 행 별 년도 출력
print(data['Date'].dt.month)# 각 행 별 월 출력
print(data['Date'].dt.month_name()) # 각 행 별 월 영어로 출력
print(data['Date'].dt.day) # 각 행 별 일 출력
print(data['Date'].dt.time) # 각 행 별 시간 출력 => 현재 데이터에는 시간이 없어서 00:00:00
print(data['Date'].dt.hour) #  현재 데이터에는 시간이 없어서 0
print(data['Date'].dt.minute) #  현재 데이터에는 시간이 없어서 0
print(data['Date'].dt.second) #  현재 데이터에는 시간이 없어서 0
print(data['Date'].dt.quarter) # 각 행 별 분기
print(data['Date'].dt.day_name()) # 요일 이름 (문자)
print(data['Date'].dt.weekday) # 각 행 별 요일 이름 (숫 자)
print(data['Date'].dt.dayofyear) # 각 행 별 연 기준 몇일째 인지
print(data['Date'].dt.days_in_month) # 각 행 별 월 일수

 

 

.shift()

시계열 데이터에서 시간의 흐름 전후로 정보를 이동시킬 때 사용한다.

data = pd.DataFrame([
    ['2024-02-22', 20153],
    ['2024-02-23', 20546],
    ['2024-02-24', 2053],
    ['2024-02-25', 2033],
    ['2024-02-26', 2234532],
    ['2024-02-27', 2653261],
], columns=["Date", "Sales"])

data['Date'] = pd.to_datetime(data['Date'])
data['sales_lag1'] = data['Sales'].shift() # 하루 전날 데이터 열 추가
data['sales_lag2'] = data['Sales'].shift(2) # 2일 전날 데이터 열 추가
data['sales_lag_1'] = data['Sales'].shift(-1) # 다음 날 데이터 열 추가
data

 

 

.rolling().mean()

시간의 흐름에 따라 일정 기간 동안 평균을 이동하면서 구하기

data = pd.DataFrame([
    ['2024-02-22', 200],
    ['2024-02-23', 300],
    ['2024-02-24', 400],
    ['2024-02-25', 50],
    ['2024-02-26', 1000],
    ['2024-02-27', 250],
], columns=["Date", "Sales"])

data['Date'] = pd.to_datetime(data['Date'])
data['sales_mean3'] = data['Sales'].rolling(3).mean() # 3일 동안의 평균
data['sales_max3'] = data['Sales'].rolling(3).max() # 3일 동안의 최대값
data['sales_mean3_min_periods1'] = data['Sales'].rolling(3, min_periods=1).mean() # 3일 동안의 평균을 계산하는데, 하나의 값이라도 존재하면 바로 계산
data

 

 

.diff()

특정 시점 데이터, 이전 시점 데이터와의 차이 구하기

  • .diff() : 현재 - 하루 전
  • .diff(2) : 현재 - 2일 전
data = pd.DataFrame([
    ['2024-02-22', 200],
    ['2024-02-23', 300],
    ['2024-02-24', 400],
    ['2024-02-25', 50],
    ['2024-02-26', 1000],
    ['2024-02-27', 250],
], columns=["Date", "Sales"])

data['Date'] = pd.to_datetime(data['Date'])
data['diff1'] = data['Sales'].diff() # 현재 - 하루 전 값
data['diff2'] = data['Sales'].diff(2) # 현재 - 2일 전 값
data['diff3'] = data['Sales'].diff(3) # 현재 - 3일 전 값

data

728x90

'Language > Python' 카테고리의 다른 글

[Pandas] 데이터분석을 위한 데이터 전처리  (2) 2024.03.01
[Pandas] Pandas 기초  (0) 2024.03.01
[Numpy] Numpy 기초  (0) 2024.02.29
[Python] List, Dictionary  (0) 2024.02.28

데이터 처리

데이터 전처리에는 두 단계가 있다.

1. 원본 데이터에서 하나의 데이터셋으로 데이터 구조를 만드는 것 ( 데이터 분석을 위한 전처리 )

2. 모델링을 위한 데이터 전처리 ( ML, DL 모델링 )

이 두 가지 여기서는 데이터 분석을 위한 데이터 전처리하는 방법에 대해 설명할 것이다.

 

목차

  1. 데이터프레임 변경
  2. 데이터프레임 결

1. 데이터프레임 변경

열 이름 변경

  • columns 속성 변경
  • rename() 메소드 사용

columns

dataframe.columns = update 한 컬럼 이름 리스트

# columns 속성 변경
df.columns = ['name', 'scores', 'age']

 

 

rename() 

dataframe.rename(columns={"기존 이름" : "변경 이름"})

# rename() 메소드 변경: columns={"기존 이름": "변경할 이름"}
df.rename(columns={'NAME': 'name', 'SCORES', 'scores', 'AGE': 'age'})

 

열 추가

  • df['new column name'] = new column data : 데이터프레임 맨 뒤에 열 추가
  • df.insert(index, columnName, value) : 지정한 위치에 열 추가

df['new column name'] = new column data

# df['추가할 열 이름'] = 추가할 열 데이터
# sex = ['Female', 'Male', 'Female', ... ]
df['sex'] = sex

 

dataframe.insert(index, columnName, value)

# df.insert(index, new_column_name, new_column_data)
sex = ['Female', 'Male', 'Male', ... ]
df.insert(3, 'sex', sex)

 

 

열 삭제

df.drop(column_name, axis, inplace )

  • column_name: 삭제하고자 하는 열 이름
  • axis=0: 행 삭제(기본 값)
  • axis=1: 열 삭제
  • inplace=True or False
    • True: 삭제한 결과를 데이터에 반영
    • False: 삭제한 결과를 데이터에 반영하지 않고 삭제한 결과를 조회만.
# 열 하나 삭제
df.drop('column1', axis=1, inplace=True)

# 열 두 개 삭제
df.drop(['column1', 'column2'], axis=1, inplace=True)

 

 

값 변경

열 전체 값 변경

# column1의 모든 값을 0으로 변경
df['column1'] = 0

조건에 의한 변경

  • .loc
  • np.where

.loc

# df['column1']의 값이 30보다 큰 경우의 모든 값을 'column1'의 값을 100으로 변경
df.loc[df['column1'] > 30, 'column1'] = 100

 

np.where(조건문, 참, 거짓)

# column1 의 값이 30보다 큰 경우 100, 아니면 값 그대로
df['column1'] = np.where(df['column1'] > 30, 100, df['column1'])

 

기존 값을 다른 값으로 변경: map()

# male -> 1, female -> 0
df['sex'] = df['sex'].map({'male': 1, 'female':0})

 

숫자형 변수를 범주형 변수로 변경: cut()

  • pd.cut(df[자를 열 이름], 몇 등분할지, 나눈 값을 어떤 범주이름으로 할지 리스트)
# age열의 값들을 3등분하여 각각 y, m o로 명칭한 값을 age_group 열로 추가
df['age_group'] = pd.cut(df['age'], 3, ['y', 'm', 'o'])

2. 데이터 프레임 결합

  1. pd.concat()
  2. pd.merge()

pd.concat([target1, target2, ...],axis, join)

concat 메소드는 행 기준으로 결합할지, 열 기준으로 결합할지 지정할 수 있다.

  • axis=0
    • 행 기준으로 합친다. 즉, 아래나 위로 합친다는 의미이다. 
    • 열 이름을 기준으로 붙이게 된다.
    • join = "outer" ( 기본값 )
      • 모든 행과 열을 합친다. (값이 없는 요소는 NaN으로 채운다.) 
    • join = "inner"
      • 같은 행과 열만 합친다.
  • axis=1
    • 열 기준으로 합친다. 즉, 옆으로 합친다.
    • 행 인덱스를 기준으로 붙이게 된다.
    • join = "outer" ( 기본값 )
      • 모든 행과 열을 합친다. ( 값이 없는 요소는 NaN으로 채운다.)
    • join = "inner"
      • 같은 행과 열만 합친다.

concat([data1, data2], axis=0, join="outer")

axis=0 행 기준으로 모든 행과 열을 결합 하기 때문에 다음과 같은 결과가 나온다.

data1 = pd.DataFrame([
    [10, 15],
    [25, 30]
])

data2 = pd.DataFrame([
    [20, 35],
    [50, 40]
])


pd.concat([data1, data2] ,axis=0, join="outer")

data1, data2
concat 결과

concat([data1, data2], axis=0, join="inner")

data1의 경우 열이 A, B이고, data2의 경우 열이 A, C이기 때문에 열의 이름이 겹치는 A의 값만 결합되게 된다.

data1 = pd.DataFrame([
    [10, 15],
    [25, 30]
])

data2 = pd.DataFrame([
    [20, 35],
    [50, 40]
])

data1.columns = ["A", "B"]
data2.columns = ["A", "C"]

print(data1, end="\n\n")
print(data2, end="\n\n")


pd.concat([data1, data2] ,axis=0, join="inner")

 

concat([data1, data2], axis=1, join="outer")

행의 인덱스를 기준으로 결합을 하는데 모든 행과 열을 합치게 된다.

data1 = pd.DataFrame([
    [10, 15],
    [25, 30]
])

data2 = pd.DataFrame([
    [20, 35],
    [50, 40]
])

data1.columns = ["A", "B"]
data2.columns = ["A", "C"]

print(data1, end="\n\n")
print(data2, end="\n\n")


pd.concat([data1, data2], axis=1, join="outer")

concat([data1, data2], axis=1, join="inner")

data1의 행은 1, 2 data2의 행은 0,1 이 있다. 

이중에서 행 인덱스가 같은 값은 1뿐이기 때문에 다음과 같은 결과값이 나온다.

 

data1 = pd.DataFrame([
    [10, 15],
    [25, 30],
    [32, 54]
])

data2 = pd.DataFrame([
    [20, 35],
    [50, 40]
])

data1.columns = ["A", "B"]
data2.columns = ["A", "C"]
data1.drop(0, inplace=True)

print(data1, end="\n\n")
print(data2, end="\n\n")


pd.concat([data1, data2], axis=1, join="inner")

pd.merge()

  • merge 메소드는 특정 열(key)의 값을 기준으로 결합한다.
  • 데이터베이스의 테이블 조인과 같다.
  • 옆으로만 결합한다.
  • 결합 방법 4가지 ( how )
    • inner: 같은 값만
    • outer: 모두
    • left:  왼쪽 dataframe은 모두, 오른쪽 dataframe 같은 값만
    • right:  오른쪽 dataframe은 모두, 왼쪽 dataframe 같은 값만

pd.merge ( inner, outer, left, right ) 한번에 출력

  • inner
    • 아래 코드에서는 같은 값이 없으므로 출력되는 것이 없다.
  • outer
    • 모두 다 결합하기 때문에 data1, data2의 모든 A값이 나오게 붙게 되고 빈 값들은 NaN으로 채워진다.
  • left
    • data1을 기준으로 결합되는데, data2에 data1과 겹치는 값이 없으므로 결과는 data1에 D열이 추가되고, D열에는 NaN으로 채워진다.
  • right
    • data2를 기준으로 결합되는데, data1에 data2와 겹치는 값이 없으므로 결과는 data2에 B, C열이 추가되고, B, C열에는 NaN으로 채워진다.
data1 = pd.DataFrame([
    [10, 15, 43],
    [25, 30, 54],
])

data2 = pd.DataFrame([
    [20, 35],
    [50, 40]
])

data1.columns = ["A", "B", "C"]
data2.columns = ["A", "D"]

print("=" * 20, "data1", "=" * 20)
print(data1, end="\n\n")
print("=" * 20, "data2", "=" * 20)
print(data2, end="\n\n")


print("=" * 20, "inner", "=" * 20)
print(pd.merge(data1,data2, how="inner"))
print()
print("=" * 20, "outer", "=" * 20)
print(pd.merge(data1,data2, how="outer"))
print()
print("=" * 20, "outer", "=" * 20)
print(pd.merge(data1,data2, how="left"))
print()
print("=" * 20, "outer", "=" * 20)
print(pd.merge(data1,data2, how="right"))

 

 

pd.pivot_table

  • groupby된 데이터를 재구성한다.
  • df.pivot_table(index, columns, values)
columnName = ["Month", "Sex", "Name", "Price"]
data = [
    [1, "Male", "James", 100],
    [1, "Male", "John", 424],
    [2, "Female", "Hana", 2321],
    [2, "Female", "Jane", 545],
    [2, "Male", "Brian", 222],
]

data = pd.DataFrame(data, columns=columnName)
print("========= DataFrame =========")
print(data, end="\n\n")

print("========= Month & Sex ==> Price.sum() =========")
data = data.groupby(['Month', 'Sex'])[['Price']].sum()
print(data, end="\n\n")

print("========= pivot =========")
data.pivot_table(index = "Month", columns = "Sex", values="Price")

 

1월에 Female 정보가 없기 때문에 NaN이 나온다.

728x90

'Language > Python' 카테고리의 다른 글

[Pandas] 시계열 데이터 처리  (0) 2024.03.01
[Pandas] Pandas 기초  (0) 2024.03.01
[Numpy] Numpy 기초  (0) 2024.02.29
[Python] List, Dictionary  (0) 2024.02.28

+ Recent posts