programing

Excel 또는 스프레드시트 열 문자를 피토닉 방식으로 숫자로 변환

kakaobank 2023. 4. 22. 09:51
반응형

Excel 또는 스프레드시트 열 문자를 피토닉 방식으로 숫자로 변환

엑셀 형식의 열을 숫자로 변환하는 좀 더 피토닉한 방법이 있나요(1부터 시작)?

동작 코드(최대 2글자):

def column_to_number(c):
    """Return number corresponding to excel-style column."""
    number=-25
    for l in c:
        if not l in string.ascii_letters:
            return False
        number+=ord(l.upper())-64+25
    return number

코드 실행:

>>> column_to_number('2')
False
>>> column_to_number('A')
1
>>> column_to_number('AB')
28

세 글자가 작동하지 않습니다.

>>> column_to_number('ABA')
54
>>> column_to_number('AAB')
54

레퍼런스: C#에서 답변한 질문

좀 더 피토닉하게 만드는 방법이 있습니다(세 개 이상의 문자로 작동하며 마법 숫자를 적게 사용함).

def col2num(col):
    num = 0
    for c in col:
        if c in string.ascii_letters:
            num = num * 26 + (ord(c.upper()) - ord('A')) + 1
    return num

또한 reduce를 사용하는 원라이너로서 다음과 같이 입력합니다(입력 내용을 확인하지 않고 읽기 쉬우므로 권장하지 않습니다.

col2num = lambda col: reduce(lambda x, y: x*26 + y, [ord(c.upper()) - ord('A') + 1 for c in col])

Python 2.7.1 및 3.5.2에서 테스트된 단일 라인

excel_col_num = lambda a: 0 if a == '' else 1 + ord(a[-1]) - ord('A') + 26 * excel_col_num(a[:-1])

excel_col_name = lambda n: '' if n <= 0 else excel_col_name((n - 1) // 26) + chr((n - 1) % 26 + ord('A'))

멀티라인도 마찬가지

def excel_column_name(n):
    """Number to Excel-style column name, e.g., 1 = A, 26 = Z, 27 = AA, 703 = AAA."""
    name = ''
    while n > 0:
        n, r = divmod (n - 1, 26)
        name = chr(r + ord('A')) + name
    return name

def excel_column_number(name):
    """Excel-style column name to number, e.g., A = 1, Z = 26, AA = 27, AAA = 703."""
    n = 0
    for c in name:
        n = n * 26 + 1 + ord(c) - ord('A')
    return n

def test (name, number):
    for n in [0, 1, 2, 3, 24, 25, 26, 27, 702, 703, 704, 2708874, 1110829947]:
        a = name(n)
        n2 = number(a)
        a2 = name(n2)
        print ("%10d  %-9s  %s" % (n, a, "ok" if a == a2 and n == n2 else "error %d %s" % (n2, a2)))

test (excel_column_name, excel_column_number)
test (excel_col_name, excel_col_num)

모든 테스트 인쇄

         0             ok
         1  A          ok
         2  B          ok
         3  C          ok
        24  X          ok
        25  Y          ok
        26  Z          ok
        27  AA         ok
       702  ZZ         ok
       703  AAA        ok
       704  AAB        ok
   2708874  EXCEL      ok
1110829947  COLUMNS    ok

openpyxl 모듈을 설치한 후 콘솔에 다음 항목을 추가할 수 있습니다.

>>> from openpyxl.utils import get_column_letter, column_index_from_string

>>> get_column_letter(1)
'A'
>>> column_index_from_string('A')
1

그냥 필요에 맞게 글자와 숫자를 바꾸세요.

여기 그것을 하는 한 가지 방법이 있다.XlsxWriter 모듈의 코드 변형입니다.

def col_to_num(col_str):
    """ Convert base26 column string to number. """
    expn = 0
    col_num = 0
    for char in reversed(col_str):
        col_num += (ord(char) - ord('A') + 1) * (26 ** expn)
        expn += 1

    return col_num


>>> col_to_num('A')
1
>>> col_to_num('AB')
28
>>> col_to_num('ABA')
729
>>> col_to_num('AAB')
704

openpyxl 사용

import openpyxl
(column_string, row) = openpyxl.cell.coordinate_from_string(address)
column = openpyxl.cell.column_index_from_string(column_string) 

VBA에서는 다음과 같은 작업을 수행할 수 있습니다.

Function columnNumber(colLetter As String) As Integer

    Dim colNumber As Integer
    Dim i As Integer

    colLetter = UCase(colLetter)
    colNumber = 0
    For i = 1 To Len(colLetter)
        colNumber = colNumber + (Asc(Mid(colLetter, Len(colLetter) - i + 1, 1)) - 64) * 26 ^ (i - 1)
    Next

    columnNumber = colNumber

End Function

Excel 공식처럼 사용할 수 있습니다. 열을 문자열(예: "AA")로 입력하고 열 길이에 관계없이 작동해야 합니다.

세 글자를 다룰 때 암호를 해독할 수 있어요 숫자를 세는 방법 때문에 26번 베이스를 사용해야 해요

저는 이 글을 읽고 엑셀 셀에서 직접 할 수 있는 방법을 찾아보기로 했습니다.Z 뒤의 열도 고려됩니다.

이 공식을 열의 임의의 행 셀에 붙여넣기만 하면 해당 번호가 표시됩니다.

=IF(LEN(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))=2,
 CODE(LEFT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1))-64*26)+
 CODE(RIGHT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1)-64),
 CODE(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))-64)

여기서의 주제는 칼럼의 글자를 잡고Code()문자 ASCII 문자 코드의 경우 64를 빼야 합니다.A64 입니다.

제가 만든 건 원라이너예요

colNameToNum = lambda cn: sum([((ord(cn[-1-pos]) - 64) * 26 ** pos) for pos in range(len(cn))])

역순으로 문자를 반복하고 1, 26, 26 * 26 등을 곱한 후 목록의 합계를 구합니다.이 방법은 긴 문자열과도 호환됩니다.

나는 그것을 다음과 같이 부른다.

print ( col Name To Num ( " AA " ) # 27

또는

print ( col Name To Num ( " XFD " ) # 허용 컬럼 중 가장 높은 컬럼이라고 생각합니다.결과 = 16384

이 오니어라이너는 상당히 사용하기 쉬운 이해와 문자열을 사용하여 사용할 수 있습니다.

sum([string.ascii_lowercase.index(c) + 26 ** i for i,c in enumerate(col_letters)])

사용하는 내용은 다음과 같습니다(이 페이지를 찾기 전에 작성).

def col_to_index(col):
    return sum((ord(c) - 64) * 26**i for i, c in enumerate(reversed(col))) - 1

일부 실행:

>>> col_to_index('A')
1
>>> col_to_index('AB')
28
>>> col_to_index('ABCD')
19010

용도:

LETTERS = list(string.ascii_uppercase)
def column_number(column_id):
    return sum([(LETTERS.index(j)+1)*(26**i) for i,j in enumerate(column_id[::-1])])

이 원라이너에는 몇 가지 부분이 있습니다.그러면 다음과 같이 설명입니다.

column_id[::-1]를 들어, 변환: "converts: " (변환: "변환")'AZ'로로 합니다.'ZA'그럴 만한 이유가 있습니다. 을 사용하다

enumerate()수 있는 것을 복복가 음음 음음 음음 음음 음)) )) ))) ) 。(0, 'Z'), (1, 'A')

관찰 결과:

 A -> 1  = (26**0)*1              # ** is the exponential operator
 B -> 2  = (26**0)*2 
 Z -> 26 = (26**0)*26
AA -> 27 = (26**0)*1  + (26**1)*1
AB -> 28 = (26**0)*2  + (26**1)*1
AZ -> 52 = (26**0)*26 + (26**1)*1  # recall that we have (0, 'Z'), (1, 'A')

「」의 column_id ★★★★★★★★★★★★★★★★★」enumerate()26일나머지는 이제 하찮다.

LETTERS.index(j)에를 나타냅니다.LETTERS

sum(): 번호 목록을 가져와서 합계를 반환합니다.

다음은 재귀적 해결 방법입니다.

def column_string_to_num(s):
    n = ord(s[-1]) - 64
    if s[:-1]:
        return 26 * (column_string_to_num(s[:-1])) + n
    else:
        return n
    
column_string_to_num("AB")
#output: 28

역방향은 유사한 방법으로 재귀적으로 정의할 수도 있습니다.

def column_num_to_string(n):
    n, rem = divmod(n - 1, 26)
    next_char = chr(65 + rem)
    if n:
        return column_string(n) + next_char
    else:
        return next_char

column_num_to_string(28)
#output: 'AB'

간결하고 우아한 루비 버전:

def col_num(col_name)
    col_name.split(//).inject(0) { |n, c| n * 26 + c.upcase.ord - "A".ord + 1 }
end

제대로 이해했는지 모르겠습니다만, 참조된 C# 코드를 python으로 "변환"하시겠습니까?그렇다면 올바른 방향으로 가고 있는 것입니다.그냥 수정해 주세요.

def column_to_number(c):
  """Return number corresponding to excel-style column."""
  sum = 0
  for l in c:
    if not l in string.ascii_letters:
      return False
    sum*=26
    sum+=ord(l.upper())-64
  return sum

다음 작업을 수행합니다.

print ws.Range("E2").Column

콜의 예:

from win32com import client
xl = client.Dispatch("Excel.Application")
wb = xl.Workbooks.Open("c:/somePath/file.xls")
xl.Visible = 1
ws = wb.Sheets("sheet 1")
print ws.Range("E2").Column

결과:

>>5

0부터 시작하는 지수(예: A = 0, B = 1 등)의 경우:

def col_to_index(col):
    A = ord('A')
    return sum(i * 26 + (ord(c) - A) for i, c in enumerate(col[::-1].upper()))

다음과 같이 일련의 곱셈 및 덧셈을 통해 수행할 수도 있습니다.'는 'A'와 .1은 입니다O(n)서 ''는n길이입니다.col.

import functools
def spreadsheet_column_encoding(col):
    return functools.reduce(
        lambda result, char: result * 26 + ord(char) - ord("A") + 1, col, 0
    )

: »ZZ=702:

0 * 26 + 90 - 65 + 1 = 26
26 * 26 + 90 - 65 + 1 = 702

★★★★★★★★★★★★★★★★★*ord('Z') = 90

숫자를 열 문자로 변환하려면 여기를 참조하십시오.나눗셈과 계수 계산을 사용하면 정반대로 할 수 있습니다.

언급URL : https://stackoverflow.com/questions/7261936/convert-an-excel-or-spreadsheet-column-letter-to-its-number-in-pythonic-fashion

반응형